php利用pcntl擴充套件實現高併發

roy711093發表於2018-09-21

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 "程式開始
";
    while($slice > 0)
    {
        $pid = pcntl_fork();
        if($pid > 0){
            $childList[$pid] = 1;
            echo $pid."
";
            //$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]);
        }
    }
}


相關文章