首先翻到官網https://wiki.swoole.com/#/coroutine/channel,
有關channel:通道,用于協程間通訊,支持多生產者協程和多消費者協程,底層自動實作了協程的切換和調度,
其構造方法:Swoole\Coroutine\Channel->__construct(int $capacity = 1),有個capacity的容量引數,一開始并不理解, 敲點代碼嘗試下,理解起來容易許多,
[root@guangzhou coroutine]# cat coroutine_channel.php <?php #開啟一鍵協程 Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]); Co\run(function(){ // 設定一個容量為1的通道 $chan = new Swoole\Coroutine\Channel(1); Swoole\Coroutine::create(function () use ($chan) { for($i = 0; $i < 6; $i++) { $chan->push( date('H:i:s') . " 資料 i:" . $i . "\n"); echo date('H:i:s') . " 第{$i}次塞資料時間\n"; } }); Swoole\Coroutine::create(function () use ($chan) { while(1) { $data = $chan->pop(); if($data){ echo date('H:i:s') . " 取資料時間\n"; echo $data . "\n"; Co::sleep(2); }else{ break; } } }); });
//看到這段代碼,你認為他的輸出情況是怎樣,先自己思考下!!
上面腳本運行后每次pop后獲取通道資料后休眠2秒,是協程模式,可能也會想當然認為每次取到資料的間隔應該是2秒??
現在運行腳本:
[root@guangzhou coroutine]# php coroutine_channel.php 06:55:32 第0次塞資料時間 06:55:32 第1次塞資料時間 06:55:32 取資料時間 06:55:32 資料 i:0 06:55:34 第2次塞資料時間 06:55:34 取資料時間 06:55:32 資料 i:1 06:55:36 第3次塞資料時間 06:55:36 取資料時間 06:55:32 資料 i:2 06:55:38 第4次塞資料時間 06:55:38 取資料時間 06:55:34 資料 i:3 06:55:40 第5次塞資料時間 06:55:40 取資料時間 06:55:36 資料 i:4 06:55:42 取資料時間 06:55:38 資料 i:5
有沒有發現前三次取資料時間點都是2秒的,第四次的資料一下子到了4秒,
經過swoole官方群的高人指點,給出了正確的執行路徑如下圖(數字從小到大是執行順序):

因為設定的capacity=1,導致第二次的push未成功,需要先pop方能繼續下去,
第一次pop后,回到第三次push回圈,程式判斷管道已滿這時將處理第一次pop的資料,又開始第四次push回圈,程式判斷管道又滿了,pop第二次push的資料,
到目前為止前三次push的資料并未進入到sleep這里,導致后續列印第一次pop資料時,塞資料時間點比取資料時間點被推后了,
從第三次資料pop后的資料都要經歷push失敗->echo+sleep->pop上一次的,這里就會有休眠2秒的時間加上pop上次時間就是4秒了,
這里有點繞,需要多思考并動手實踐,
修改capacity=10,并push回圈7次,運行程式:
[root@guangzhou coroutine]# cat coroutine_channel.php <?php #開啟一鍵協程 Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]); Co\run(function(){ // 設定一個容量為1的通道 $chan = new Swoole\Coroutine\Channel(10); Swoole\Coroutine::create(function () use ($chan) { for($i = 0; $i < 7; $i++) { $chan->push( date('H:i:s') . " 資料 i:" . $i . "\n"); echo date('H:i:s') . " 第{$i}次塞資料時間\n"; } }); Swoole\Coroutine::create(function () use ($chan) { while(1) { $data = $chan->pop(); if($data){ echo date('H:i:s') . " 取資料時間\n"; echo $data . "\n"; Co::sleep(2); }else{ break; } } }); });
執行腳本:
[root@guangzhou coroutine]# php coroutine_channel.php 07:29:22 第0次塞資料時間 07:29:22 第1次塞資料時間 07:29:22 第2次塞資料時間 07:29:22 第3次塞資料時間 07:29:22 第4次塞資料時間 07:29:22 第5次塞資料時間 07:29:22 第6次塞資料時間 07:29:22 取資料時間 07:29:22 資料 i:0 07:29:24 取資料時間 07:29:22 資料 i:1 07:29:26 取資料時間 07:29:22 資料 i:2 07:29:28 取資料時間 07:29:22 資料 i:3 07:29:30 取資料時間 07:29:22 資料 i:4 07:29:32 取資料時間 07:29:22 資料 i:5 07:29:34 取資料時間 07:29:22 資料 i:6
發現所有 i:xxx 的時間點幾乎一致,
現在得出結論capacity的作用是限制管道寫入的長度,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/139129.html
標籤:PHP
上一篇:Java 轉換 PDF 版本
