今天小編給大家分享一下swoole協程的執行流程是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
在swoole中,Swoole server接收數據在worker進程觸發onReceive回調,產生一個協程,Swoole為每個請求創建對應攜程,協程中也能創建子協程,協程在底層實現上是單線程的,因此同一時間只有一個協程在工作。
本教程操作環境:Windows10系統、Swoole4版、DELL G3電腦
什么是進程?
進程就是應用程序的啟動實例。獨立的文件資源,數據資源,內存空間。
什么是線程?
線程屬于進程,是程序的執行者。一個進程至少包含一個主線程,也可以有更多的子線程。線程有兩種調度策略,一是:分時調度,二是:搶占式調度。
什么是協程?
協程是輕量級線程,協程也是屬于線程,協程是在線程里執行的。協程的調度是用戶手動切換的,所以又叫用戶空間線程。協程的創建、切換、掛起、銷毀全部為內存操作,消耗是非常低的。協程的調度策略是:協作式調度。
Swoole 協程的原理
Swoole4 由于是單線程多進程的,同一時間同一個進程只會有一個協程在運行。
Swoole server 接收數據在 worker 進程觸發 onReceive 回調,產生一個攜程。Swoole 為每個請求創建對應攜程。協程中也能創建子協程。
協程在底層實現上是單線程的,因此同一時間只有一個協程在工作,協程的執行是串行的。
因此多任務多協程執行時,一個協程正在運行時,其他協程會停止工作。當前協程執行阻塞 IO 操作時會掛起,底層調度器會進入事件循環。當有 IO 完成事件時,底層調度器恢復事件對應的協程的執行。。所以協程不存在 IO 耗時,非常適合高并發 IO 場景。
Swoole 的協程執行流程
協程沒有 IO 等待 正常執行 PHP 代碼,不會產生執行流程切換
協程遇到 IO 等待 立即將控制權切,待 IO 完成后,重新將執行流切回原來協程切出的點
協程并行協程依次執行,同上一個邏輯
協程嵌套執行流程由外向內逐層進入,直到發生 IO,然后切到外層協程,父協程不會等待子協程結束
協程的執行順序
先來看看基礎的例子:
go(function () { echo "hello go1 \n";});echo "hello main \n";go(function () { echo "hello go2 \n";});
go() 是 \Co::create() 的縮寫, 用來創建一個協程, 接受 callback 作為參數, callback 中的代碼, 會在這個新建的協程中執行.
備注: \Swoole\Coroutine 可以簡寫為 \Co
上面的代碼執行結果:
root@b98940b00a9b /v/w/c/p/swoole# php co.phphello go1 hello main hello go2
執行結果和我們平時寫代碼的順序, 好像沒啥區別. 實際執行過程:
運行此段代碼, 系統啟動一個新進程
遇到 go(), 當前進程中生成一個協程, 協程中輸出 heelo go1, 協程退出
進程繼續向下執行代碼, 輸出 hello main
再生成一個協程, 協程中輸出heelo go2, 協程退出
運行此段代碼, 系統啟動一個新進程. 如果不理解這句話, 你可以使用如下代碼:
// co.php<?phpsleep(100);
執行并使用 ps aux 查看系統中的進程:
root@b98940b00a9b /v/w/c/p/swoole# php co.php &? root@b98940b00a9b /v/w/c/p/swoole# ps auxPID USER TIME COMMAND 1 root 0:00 php -a 10 root 0:00 sh 19 root 0:01 fish 749 root 0:00 php co.php 760 root 0:00 ps aux
我們來稍微改一改, 體驗協程的調度:
use Co;go(function () { Co::sleep(1); // 只新增了一行代碼 echo "hello go1 \n";});echo "hello main \n";go(function () { echo "hello go2 \n";}); \Co::sleep() 函數功能和 sleep() 差不多, 但是它模擬的是 IO等待(IO后面會細講). 執行的結果如下: root@b98940b00a9b /v/w/c/p/swoole# php co.phphello main hello go2 hello go1
怎么不是順序執行的呢? 實際執行過程:
運行此段代碼, 系統啟動一個新進程
遇到 go(), 當前進程中生成一個協程
協程中遇到 IO阻塞 (這里是 Co::sleep() 模擬出的 IO等待), 協程讓出控制, 進入協程調度隊列
進程繼續向下執行, 輸出 hello main
執行下一個協程, 輸出 hello go2
之前的協程準備就緒, 繼續執行, 輸出 hello go1
到這里, 已經可以看到 swoole 中 協程與進程的關系, 以及 協程的調度, 我們再改一改剛才的程序:
go(function () { Co::sleep(1); echo "hello go1 \n";});echo "hello main \n";go(function () { Co::sleep(1); echo "hello go2 \n";});
我想你已經知道輸出是什么樣子了:
root@b98940b00a9b /v/w/c/p/swoole# php co.phphello main hello go1 hello go2
以上就是“swoole協程的執行流程是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。