国产chinesehdxxxx野外,国产av无码专区亚洲av琪琪,播放男人添女人下边视频,成人国产精品一区二区免费看,chinese丰满人妻videos

Swoole 編程須知

2022-07-12 11:22 更新

編程須知

這個頻道內會詳細介紹異步編程與同步編程的不同之處以及需要注意的事項。

注意事項

  • 不要在代碼中執(zhí)行sleep以及其他睡眠函數(shù),這樣會導致整個進程阻塞
  • exit/die是危險的,會導致worker進程退出
  • 可通過register_shutdown_function來捕獲致命錯誤,在進程異常退出時做一些請求工作
  • PHP代碼中如果有異常拋出,必須在回調函數(shù)中進行try/catch捕獲異常,否則會導致工作進程退出
  • swoole不支持set_exception_handler,必須使用try/catch方式處理異常
  • Worker進程不得共用同一個RedisMySQL等網(wǎng)絡服務客戶端,Redis/MySQL創(chuàng)建連接的相關代碼可以放到onWorkerStart回調函數(shù)中。

類/函數(shù)重復定義

新手非常容易犯這個錯誤,由于swoole是常駐內存的,所以加載類/函數(shù)定義的文件后不會釋放。因此引入類/函數(shù)的php文件時必須要使用include_oncerequire_once,否會發(fā)生cannot redeclare function/class 的致命錯誤。

內存管理

PHP守護進程與普通Web程序的變量生命周期、內存管理方式完全不同。請參考 swoole_server內存管理 頁面。編寫swoole_server或其他常駐進程時需要特別注意。

進程隔離

進程隔離也是很多新手經(jīng)常遇到的問題。修改了全局變量的值,為什么不生效,原因就是全局變量在不同的進程,內存空間是隔離的,所以無效。所以使用swoole開發(fā)Server程序需要了解進程隔離問題。

  • 不同的進程中PHP變量不是共享,即使是全局變量,在A進程內修改了它的值,在B進程內是無效的
  • 如果需要在不同的Worker進程內共享數(shù)據(jù),可以用Redis、MySQL、文件、Swoole\Table、APCushmget等工具實現(xiàn)
  • 不同進程的文件句柄是隔離的,所以在A進程創(chuàng)建的Socket連接或打開的文件,在B進程內是無效,即使是將它的fd發(fā)送到B進程也是不可用的

sleep/usleep的影響

在異步IO的程序中,不得使用sleep/usleep/time_sleep_until/time_nanosleep。(下文中使用sleep泛指所有睡眠函數(shù))

  • sleep函數(shù)會使進程陷入睡眠阻塞
  • 直到指定的時間后操作系統(tǒng)才會重新喚醒當前的進程
  • sleep過程中,只有信號可以打斷
  • 由于swoole的信號處理是基于signalfd實現(xiàn)的,所以即使發(fā)送信號也無法中斷sleep

swoole提供的swoole_event_add、swoole_timer_tick、swoole_timer_after、swoole_process::signal、異步swoole_client 在進程sleep后會停止工作。swoole_server也無法再處理新的請求。

實例程序

$serv = new swoole_server("127.0.0.1", 9501);
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
    sleep(100);
    $serv->send($fd, 'Swoole: '.$data);
});
$serv->start();

onReceive事件中執(zhí)行了sleep函數(shù),server在100秒內無法再收到任何客戶端請求。


exit/die函數(shù)的影響

在swoole程序中禁止使用exit/die,如果PHP代碼中有exit/die,當前工作的Worker進程、Task進程、User進程、以及swoole_process進程會立即退出。

建議使用try/catch的方式替換exit/die,實現(xiàn)中斷執(zhí)行跳出PHP函數(shù)調用棧。

function swoole_exit($msg)
{
    //php-fpm的環(huán)境
    if (ENV=='php')
    {
        exit($msg);
    }
    //swoole的環(huán)境
    else
    {
        throw new Swoole\ExitException($msg);
    }
}

異常處理的方式比exit/die更友好,因為異常是可控的,exit/die不可控。在最外層進行try/catch即可捕獲異常,僅終止當前的任務。Worker進程可以繼續(xù)處理新的請求,而exit/die會導致進程直接退出,當前進程保存的所有變量和資源都會被銷毀。如果進程內還有其他任務要處理,遇到exit/die也將全部丟棄。


while循環(huán)的影響

異步程序如果遇到死循環(huán),事件將無法觸發(fā)。異步IO程序使用Reactor模型,運行過程中必須在reactor->wait處輪詢。如果遇到死循環(huán),那么程序的控制權就在while中了,reactor無法得到控制權,無法檢測事件,所以IO事件回調函數(shù)也將無法觸發(fā)。

密集運算的代碼不是阻塞

實例程序

$serv = new swoole_server("127.0.0.1", 9501);
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
    while(1)
    {
        $i ++;
    }
    $serv->send($fd, 'Swoole: '.$data);
});
$serv->start();

onReceive事件中執(zhí)行了死循環(huán),server在無法再收到任何客戶端請求,必須等待循環(huán)結束才能繼續(xù)處理新的事件。



以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號