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]);
}
}
}