Swoole AsyncIO實例

2022-07-12 11:26 更新

Swoole AsyncIO異步文件讀寫介紹

swoole1.6.12后增加了異步文件讀寫,異步DNS等特性。自此建立了完整的異步并行API。

  • swoole_server的Task進程是同步阻塞的,沒有EventLoop,因此無法使除定時器之外的用任何異步IO
  • signalfd是Linux2.6.27提供文件句柄方式處理信號特性,優(yōu)點是可以將信號加入到EventLoop中,Reactor操作不會被信號打斷提高了性能。缺點是有些同步阻塞的程序可能會出現(xiàn)問題,無法從阻塞中中斷,可以使用swoole_async_set關(guān)閉signalfd特性

Swoole支持3種類型的異步文件讀寫IO,可以使用swoole_async_set來設(shè)置AIO模式。

swoole_async_set

此函數(shù)可以設(shè)置異步IO相關(guān)的選項。

swoole_async_set(array $setting);
  • thread_num 設(shè)置異步文件IO線程的數(shù)量
  • aio_mode 設(shè)置異步文件IO的操作模式,目前支持SWOOLE_AIO_BASE(使用類似于Node.js的線程池同步阻塞模擬異步)、SWOOLE_AIO_LINUX(Linux Native AIO) 2種模式
  • enable_signalfd 開啟和關(guān)閉signalfd特性的使用
  • socket_buffer_size 設(shè)置SOCKET內(nèi)存緩存區(qū)尺寸
  • socket_dontwait 在內(nèi)存緩存區(qū)已滿的情況下禁止底層阻塞等待

Linux Native AIO的優(yōu)點是由內(nèi)核支持是真正的異步文件IO,缺點是只支持DirectIO,無法利用到系統(tǒng)的PageCache

swoole_async模塊目前為實驗性質(zhì),不建議在生產(chǎn)環(huán)境使用,請使用PHP的文件讀寫函數(shù)。

Linux原生異步IO

基于Linux Native AIO系統(tǒng)調(diào)用,是真正的異步IO,并非阻塞模擬。

優(yōu)點:

  • 所有操作均在一個線程內(nèi)完成,不需要開線程池
  • 不依賴線程執(zhí)行IO,所以并發(fā)可以非常大

缺點:

  • 只支持DriectIO,無法利用PageCache,所有對文件讀寫都會直接操作磁盤

線程池模式異步IO

基于線程池模擬實現(xiàn),文件讀寫請求投遞到任務(wù)隊列,然后由AIO線程讀寫文件,完成后通知主線程。AIO線程本身是同步阻塞的。所以并非真正的異步IO。

優(yōu)點:

  • 可以利用操作系統(tǒng)PageCache,讀寫熱數(shù)據(jù)性能非常高,等于讀內(nèi)存

可修改thread_num項設(shè)置啟用的AIO線程數(shù)量

缺點:

  • 并發(fā)較差,不支持同時讀寫大量文件,最大并發(fā)受限與AIO的線程數(shù)量

簡單實例:

$fp = stream_socket_client("tcp://127.0.0.1:80", $code, $msg, 3);
$http_request = "GET /index.html HTTP/1.1\r\n\r\n";
fwrite($fp, $http_request);
Swoole\Event::add($fp, function($fp){
    echo fread($fp, 8192);
    swoole_event_del($fp);
    fclose($fp);
});
Swoole\Timer::after(2000, function() {
    echo "2000ms timeout\n";
});
Swoole\Timer::tick(1000, function() {
    echo "1000ms interval\n";
});



以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號