編程學習網(wǎng) > PHP技術(shù) > swoole > 關(guān)于協(xié)程的優(yōu)點以及swoole 協(xié)程的使用場景
2021
06-17

關(guān)于協(xié)程的優(yōu)點以及swoole 協(xié)程的使用場景

現(xiàn)在我們來繼續(xù)看下協(xié)程的執(zhí)行順序.


協(xié)程的優(yōu)點

協(xié)程的運行是交叉式運行(串行),只要你發(fā)起了一次協(xié)程切換,則會立馬暫停當前協(xié)程,去運行下一個協(xié)程,直到下次代碼調(diào)度回協(xié)程.看到上面的執(zhí)行順序,你可能還是不能理解協(xié)程的優(yōu)點,這個其實是一個很簡單的概念,舉個例子:

小明燒開水需要10分鐘,刷牙需要3分鐘,吃早餐需要5分鐘,請問做完這些事情總共需要多少分鐘?

答案是10分鐘,因為在燒開水這個步驟時,不需要坐在那里看水壺燒(異步,io耗時)可以先去刷牙,然后去吃早餐

協(xié)程的優(yōu)點主要在于這里,當遇上io耗時的情況時,這部分的等待時間我們其實可以節(jié)約出來,去先處理其他代碼邏輯的,直到io完成再繼續(xù)執(zhí)行之前的代碼.

沒錯,協(xié)程的優(yōu)點就在于這個.

swoole協(xié)程

swoole中,已經(jīng)自帶了協(xié)程管理器,以及異步io的擴展(redis.mysql,http客戶端等),我們只要安裝好swoole擴展,就可以直接使用協(xié)程了,例如以下代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$start_time = time();
/*for ($i = 0; $i <= 500; $i++) {
    go(function ()use($i,$start_time){
        $cli = new Swoole\Coroutine\Http\Client('www.baidu.com', 443,true);
        $cli->setHeaders([
            'Host' => "www.baidu.com",
            "User-Agent" => 'Chrome/49.0.2587.3',
            'Accept' => 'text/html,application/xhtml+xml,application/xml',
            'Accept-Encoding' => 'gzip',
        ]);
        $cli->set([ 'timeout' => 0.11]);
        $cli->get('/');
        $cli->close();
        echo  "協(xié)程{$i}已完成,耗時".(time()-$start_time).PHP_EOL;
    });
}*/
$start_time = time();
for ($i = 0; $i <= 500; $i++) {
    $url     = 'https://www.baidu.com/';
    $content = file_get_contents($url);
    echo "普通{$i}已完成\n";
}
echo "非攜程完成時間:" . (time() - $start_time);

在非協(xié)程環(huán)境,它的執(zhí)行順序和執(zhí)行時間如下:


而在注釋掉非協(xié)程代碼,協(xié)程環(huán)境運行下,它的執(zhí)行順序和時間如下:


為什么會這樣呢?我說下具體的流程:

非協(xié)程流程

1:先執(zhí)行$i=0

2:通過file_get_contents獲取網(wǎng)頁內(nèi)容

3:獲取成功后在進行輸出: 普通0已完成

4:繼續(xù)執(zhí)行$i=1

...

協(xié)程流程

1:先執(zhí)行$i=0

2:通過異步client類,去請求https://www.baidu.com

3:協(xié)程切換不等待獲取網(wǎng)頁內(nèi)容,直接跳到$i=1

4:通過異步client類,去請求https://www.baidu.com

....

n:$i=0的請求內(nèi)容已經(jīng)完成,切換回$i=0后面的代碼,輸出"協(xié)程0已完成,耗時0"

n+1:通過異步client類,去請求https://www.baidu.com,協(xié)程切換不等待獲取網(wǎng)頁內(nèi)容,直接跳到$i=n+2

n+2:$i=n的請求內(nèi)容已經(jīng)完成,切換回$i=n后面的代碼,輸出"協(xié)程n已完成,耗時5"

....


由這2個流程可以看出一個不同之處:非協(xié)程需要等待請求網(wǎng)頁的時間,而協(xié)程直接跳過了等待的時間,繼續(xù)往下執(zhí)行,

也就是上面說的"小明燒開水的時間先去刷牙"

然后,由于協(xié)程沒有了io耗時,執(zhí)行速度大大提高,假設請求一次網(wǎng)站需要0.05秒,那500次循環(huán)就相當于節(jié)省了25秒,這就是為什么協(xié)程適合在高并發(fā)io場景的原因了

以上就是“關(guān)于協(xié)程的優(yōu)點以及swoole 協(xié)程的使用場景”的所有內(nèi)容,希望能夠幫到大家,如果想要獲取更多相關(guān)資訊歡迎關(guān)注編程學習網(wǎng)

掃碼二維碼 獲取免費視頻學習資料

Python編程學習

查 看2022高級編程視頻教程免費獲取