從4.0版本開始swoole提供了完整的協程(Coroutine)+ 通道(channel)特性,帶來全新的CSP編程模型。
應用層可使用完全同步的編程方式,底層自動實現異步IO。? ? ? ? ? ? ? ? ? ? (推薦學習: swoole視頻教程)
go(function?()?{ ????$redis?=?new?SwooleCoroutineRedis(); ????$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_idn"; }); //處理異步任務 $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()返回結果。