php 利用pcntl擴展實現高併發

pcntl_fork官方描述:
pcntl_fork — 在當前進程當前位置產生分支(子進程)。譯註:fork是創建了一個子進程,父進程和子進程 都從fork的位置開始向下繼續執行,不同的是父進程執行過程中,得到的fork返回值爲子進程 號,而子進程得到的是0。

通過一段代碼來理解pcntl_fork如何進行多進程併發執行的

$i = 2;
while($i >= 0){
$pid = pcntl_fork();
if($pid > 0){
//當前處於父進程中
}elseif($pid == 0){
//這裏是子進程邏輯
exit();//子進程跑完了必須退出。否則子進程會繼續執行循環創建新的進程
}else{
//進程創建失敗
}

當前進程通過pcntl_fork創建了一個子進程,創建完成後當前進程繼續執行,此時$pid爲創建子進程的進程id所以會進入pid > 0 的判斷區塊。同時,當父進程執行pcntl_fork時,php又會重新開啓一個進程。該進程會拷貝父進程的變量,並且從pcntl_fork之後開始執行,因爲進程爲子進程,所以pid爲0,會執行pid==0裏面的邏輯。子進程邏輯跑完了建議退出,否則會繼續執行while循環。

100個號碼批量分成10個進程發送示例

//隨機取100條數據
$mobileList = ['135***','139***',...,'152*****'];

insert($data);

function insert(array $phoneList){
    $cnt = count($phoneList);  //測試數組大小
    $slice = 10;  //需要調用的進程數量
    $master = array_chunk($phoneList,floor($cnt/(10)));
    $childList = [];
    echo "進程開始\r\n";
    while($slice > 0)
    {
        $pid = pcntl_fork();
        if($pid > 0){
            $childList[$pid] = 1;
            echo $pid."\r\n";
            //$pid>0表示當前還在執行父進程的代碼
            //這裏最好啥都不做,每次執行pcntl_fork都會執行這裏的代碼。
            //這裏的代碼執行完之後 會將$pid設置爲0,然後jump到pcntl_fork代碼之後,重新做判斷;
        }elseif($pid == 0){
            //這裏寫我們的邏輯
            foreach($master[$slice-1] as $val)
            {
                sendMessage();//發送短信
            }
            //子進程執行完之後務必需要關閉;
            exit();
        }else
        {
            //程序發生錯誤也需要關閉程序
            exit();
        }
        $slice--;
    }

    // 等待所有子進程結束後回收資源
    while(!empty($childList)){
        $childPid = pcntl_wait($status);
        if ($childPid > 0){
            unset($childList[$childPid]);
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章