workerman運行分析--主進程流程

基本上,workerman使用多進程的方式、使用libevent事件監聽網絡鏈接,達到高併發。它與nginx的進程模型類似,鏈接的處理,是由子進程完成的,主進程主要的工做是:
php

  1.  監聽端口,生成子進程要共享的server_socketnginx

  2. 監聽傳遞給本身的信號,如reload restart等,並進行相應處理網絡

  3. 監聽子進程退出的事件,並及啓動新的子進程補上併發

master進程(master進程會先創建好須要listen的socket)--------fork生成子進程workers,繼承socket(此時workers子進程們都繼承了父進程master的全部屬性,固然也包括已經創建好的socket,固然不是同一個socket,只是每一個進程的這個socket會監控在同一個ip地址與端口的網絡事件,這個在網絡協議裏面是容許的)------當一個鏈接進入,產生驚羣現象。socket

workerman中對驚羣事件沒有特殊處理,只是簡單地忽略掉它了,這個對性能影響也很小,對業務更沒有影響。函數

使用多個子進程,就能夠充分利用多個cpu,並顯著提升併發鏈接和處理能力。高併發


一,主進程的掛起原理性能

主進程監聽好端口,生成子進程後,自身就處於掛起狀態,只處理兩件事件:監聽信號、監聽是否有子進程退出,實現代碼見Worker::monitorWorkers方法spa

while(1) {
    pcntl_signal_dispatch();
    // 掛起進程,直到有子進程退出或者被信號打斷
    $status = 0;
    $pid = pcntl_wait($status, WUNTRACED);
            // 若是有信號到來,嘗試觸發信號處理函數
    pcntl_signal_dispatch();
    
    if($pid > 0){
        //若是有子進程退出 則嘗試fork一個子進程
    }else{
        //說明收到了信號
    }
}

讓進程掛起的關鍵就是調用pcntl_wait函數,它會一直等待、直到收到信號或有子進程退出時返回,返回值就是退出的子進程pidrest

pcntl_wait第二個參數可設爲:

WNOHANG   沒有子進程退出時,當即返回,顯然它不能掛起進程

WUNTRACED  子進程已經退出時,當即返回,這纔是實現進程掛起的關鍵。

正由於主進程一直是掛起狀態,因此它並不消耗系統資源。

咱們調用stop|restart|reload|status|kill命令,實際上是給已經運行的主進程發送相關信號。

相關文章
相關標籤/搜索