從4.0版本開始Swoole提供了完整的協程(Coroutine) 通道(Channel)特性,帶來全新的CSP程式設計模型。
應用程式層可使用完全同步的程式設計方式,底層自動實作非同步IO。 (推薦學習: swoole影片教學)
go(function () { $redis = new Swoole\Coroutine\Redis(); $redis->connect('127.0.0.1', 6379); $val = $redis->get('key'); });
4.0.0或更高版本僅支援PHP7
4.0.1版本開始移除了--enable-coroutine編譯選項,改為動態配置
協程可以理解為純用戶狀態的線程,其透過協作而不是搶佔來進行切換。相對於進程或線程,協程所有的操作都可以在使用者態完成,創建和切換的消耗更低。
Swoole可以為每個請求建立對應的協程,根據IO的狀態來合理的調度協程,這會帶來了以下優勢:
開發者可以無感知的以同步的程式碼編寫方式達到非同步IO的效果和效能,避免了傳統非同步回呼所帶來的離散的程式碼邏輯和陷入多層回呼中導致程式碼無法維護
同時由於底層封裝了協程,所以對比傳統的PHP層協程框架,開發者不需要使用yield關鍵字來標識一個協程IO操作,所以不再需要對yield的語義進行深入理解以及對每一級的調用都修改為yield,這極大的提高了開發效率
可以滿足大部分開發者的需求。對於私有協議,開發者可以使用協程的TCP或UDP介面去方便的封裝。
在Server程式中如果需要執行很耗時的操作,例如一個聊天伺服器發送廣播,Web伺服器中發送郵件。如果直接去執行這些函數就會阻塞目前進程,導致伺服器回應變慢。
Swoole提供了非同步任務處理的功能,可以投遞一個非同步任務到TaskWorker進程池中執行,不影響目前請求的處理速度。
程式碼
基於第一個TCP伺服器,只需要增加onTask和onFinish2個事件回呼函數。另外需要設定task進程數量,可以依照任務的耗時和任務量配置適量的task進程。
$serv = new swoole_server("127.0.0.1", 9501); //设置异步任务的工作进程数量 $serv->set(array('task_worker_num' => 4)); $serv->on('receive', function($serv, $fd, $from_id, $data) { //投递异步任务 $task_id = $serv->task($data); echo "Dispath AsyncTask: id=$task_id\n"; }); //处理异步任务 $serv->on('task', function ($serv, $task_id, $from_id, $data) { echo "New AsyncTask[id=$task_id]".PHP_EOL; //返回任务执行的结果 $serv->finish("$data -> OK"); }); //处理异步任务的结果 $serv->on('finish', function ($serv, $task_id, $data) { echo "AsyncTask[$task_id] Finish: $data".PHP_EOL; }); $serv->start();
呼叫$serv->task()後,程式立即傳回,繼續向下執行程式碼。 onTask回呼函數Task進程池內被非同步執行。執行完成後呼叫$serv->finish()回傳結果。
以上是swoole協程和非同步區別的詳細內容。更多資訊請關注PHP中文網其他相關文章!