協程要求目前正在執行的任務自動把控制權回傳給調度器,這樣就可以繼續執行其他任務。這與搶佔式的多任務正好相反, 搶佔多任務的調度器可以強制中斷正在運行的任務, 不管它自己有沒有意願。
如果只依賴程式自動交出控制的話,那麼某些惡意程式將會很容易佔用全部 CPU 時間而不與其他任務共享。
協程的調度是由協程自身主動讓出控制權到外層調度器實現的
回到剛才生成器實現xrange 函數的例子,整個執行過程的交替可以用下圖來表示:
協程可以理解為純用戶態的線程,透過協作而不是搶佔來進行任務切換。 (推薦學習:PHP程式設計從入門到精通)
相對於進程或線程,協程所有的操作都可以在用戶狀態而非作業系統內核態完成,創建和切換的消耗非常低。
簡單的說協程 就是提供一種方法來中斷當前任務的執行,保存當前的局部變量,下次再過來又可以恢復當前局部變量繼續執行。
協程協程的支援是在生成器的基礎上, 增加了可以回送資料給生成器的功能(呼叫者發送資料給被呼叫的生成器函數). 這就把生成器到呼叫者的單向通訊轉變為兩者之間的雙向通訊.
使用協程後的程式碼
初稿,手動調整生成器執行
# 本代码手动调整了进程执行代码的顺序,当然本代码实现不用协程也可以,只是利用本流程说明协程作用 # 生成器给了我们函数中断,协程[生成器send]给了我们重新唤起生成器函数的能力 function printNumWithGen($max) { for ($i=0; $i<$max; $i++ ) { $res = yield $i; echo $res; } } $gen1 = printNumWithGen(3); $gen2 = printNumWithGen(3); // 手动执行caller1 再 caller2 $gen1->send("调度者: caller1 打印:" . $gen1->current() . PHP_EOL); $gen2->send("调度者: caller2 打印:" . $gen2->current() . PHP_EOL); // 手动执行caller1 再 caller2 $gen1->send("调度者: caller1 打印:" . $gen1->current() . PHP_EOL); $gen2->send("调度者: caller2 打印:" . $gen2->current() . PHP_EOL); // 手动执行caller2 再 caller1 $gen2->send("调度者: caller2 打印:" . $gen2->current() . PHP_EOL); $gen1->send("调度者: caller1 打印:" . $gen1->current() . PHP_EOL); # output 调度者: caller1 打印:0 调度者: caller2 打印:0 调度者: caller1 打印:1 调度者: caller2 打印:1 调度者: caller2 打印:2 调度者: caller1 打印:2
以上是php協程是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!