php:多進程執行任務

需求

對指定數量的多個任務併發執行,並控制進程數php

進程&線程:

進程間相互獨立,不影響。併發

代碼示例:函數

<?php

$task = 0; //任務id
$taskNum = 10; //任務總數
$processNumLimit = 2; //子進程總量限制

while(true){
   //產生分支
   $processid = pcntl_fork();

   //建立子進程失敗
   if( $processid == -1 ){
       echo "create process error!\n";
       exit(1);
   }
   //主進程,得到子進程pid
   elseif($processid){
       $task++; //下一個任務

       $currentProcessid = posix_getpid(); //當前進程的Id
       $parentProcessid = posix_getppid(); // 父級進程的ID
       $phpProcessid = getmypid(); //當前php進程的id
       echo "task:",$task,"\tprocessid:",$processid,"\tcurrentProcessid:",$currentProcessid,"\tparentProcessid:",$parentProcessid,"\tphpProcessid:",$phpProcessid,"\n";

       //控制進程數
       if($task >= $processNumLimit) {
           echo "wait chl start!\n";
           $exitid = pcntl_wait($status); //等待退出
           echo "wait chl end!extid:",$exitid,"\tstatus:",$status,"\n";
       }
       
       //任務總量控制
       if($task >= $taskNum) {
           echo "taskNum enough!\n";
           break;
       }
   }
   //processid=0爲新建立的進程
   else{
       //模擬不一樣任務的不一樣執行時長
       $sleep = rand(1, 5);

       $currentProcessid = posix_getpid(); //當前進程的Id
       $parentProcessid = posix_getppid(); // 父級進程的ID
       $phpProcessid = getmypid(); //當前php進程的id
       echo "task:",$task,"\tprocessid:",$processid,"\tcurrentProcessid:",$currentProcessid,"\tparentProcessid:",$parentProcessid,"\tphpProcessid:",$phpProcessid,"\tsleep:",$sleep,"\tbegin!\n";

       sleep($sleep);

       echo "task:",$task,"\tprocessid:",$processid,"\tcurrentProcessid:",$currentProcessid,"\tparentProcessid:",$parentProcessid,"\tphpProcessid:",$phpProcessid,"\tsleep:",$sleep,"\tend!\n";
       
       exit(0); //子進程執行完後退出,防止進入循環建立子進程
   }
}

執行的結果:線程

task:1    processid:32225    currentProcessid:32224    parentProcessid:15053    phpProcessid:32224
task:0    processid:0    currentProcessid:32225    parentProcessid:32224    phpProcessid:32225    sleep:5    begin!
task:2    processid:32226    currentProcessid:32224    parentProcessid:15053    phpProcessid:32224
wait chl start!
task:1    processid:0    currentProcessid:32226    parentProcessid:32224    phpProcessid:32226    sleep:2    begin!
task:1    processid:0    currentProcessid:32226    parentProcessid:32224    phpProcessid:32226    sleep:2    end!
wait chl end!extid:32226    status:0
task:3    processid:32228    currentProcessid:32224    parentProcessid:15053    phpProcessid:32224
wait chl start!
task:2    processid:0    currentProcessid:32228    parentProcessid:32224    phpProcessid:32228    sleep:1    begin!
task:2    processid:0    currentProcessid:32228    parentProcessid:32224    phpProcessid:32228    sleep:1    end!
wait chl end!extid:32228    status:0
task:4    processid:32229    currentProcessid:32224    parentProcessid:15053    phpProcessid:32224
wait chl start!
task:3    processid:0    currentProcessid:32229    parentProcessid:32224    phpProcessid:32229    sleep:2    begin!
task:0    processid:0    currentProcessid:32225    parentProcessid:32224    phpProcessid:32225    sleep:5    end!
wait chl end!extid:32225    status:0
task:5    processid:32270    currentProcessid:32224    parentProcessid:15053    phpProcessid:32224
wait chl start!
task:4    processid:0    currentProcessid:32270    parentProcessid:32224    phpProcessid:32270    sleep:1    begin!
task:3    processid:0    currentProcessid:32229    parentProcessid:32224    phpProcessid:32229    sleep:2    end!
wait chl end!extid:32229    status:0
task:6    processid:32271    currentProcessid:32224    parentProcessid:15053    phpProcessid:32224
wait chl start!
task:5    processid:0    currentProcessid:32271    parentProcessid:32224    phpProcessid:32271    sleep:4    begin!
task:4    processid:0    currentProcessid:32270    parentProcessid:32224    phpProcessid:32270    sleep:1    end!
wait chl end!extid:32270    status:0
task:7    processid:32273    currentProcessid:32224    parentProcessid:15053    phpProcessid:32224
wait chl start!
task:6    processid:0    currentProcessid:32273    parentProcessid:32224    phpProcessid:32273    sleep:1    begin!
task:6    processid:0    currentProcessid:32273    parentProcessid:32224    phpProcessid:32273    sleep:1    end!
wait chl end!extid:32273    status:0
task:8    processid:32274    currentProcessid:32224    parentProcessid:15053    phpProcessid:32224
wait chl start!
task:7    processid:0    currentProcessid:32274    parentProcessid:32224    phpProcessid:32274    sleep:2    begin!
task:5    processid:0    currentProcessid:32271    parentProcessid:32224    phpProcessid:32271    sleep:4    end!
task:7    processid:0    currentProcessid:32274    parentProcessid:32224    phpProcessid:32274    sleep:2    end!
wait chl end!extid:32274    status:0
task:9    processid:32277    currentProcessid:32224    parentProcessid:15053    phpProcessid:32224
wait chl start!
wait chl end!extid:32271    status:0
task:8    processid:0    currentProcessid:32277    parentProcessid:32224    phpProcessid:32277    sleep:2    begin!
task:10    processid:32278    currentProcessid:32224    parentProcessid:15053    phpProcessid:32224
wait chl start!
task:9    processid:0    currentProcessid:32278    parentProcessid:32224    phpProcessid:32278    sleep:2    begin!
task:8    processid:0    currentProcessid:32277    parentProcessid:32224    phpProcessid:32277    sleep:2    end!
task:9    processid:0    currentProcessid:32278    parentProcessid:32224    phpProcessid:32278    sleep:2    end!
wait chl end!extid:32277    status:0
taskNum enough

執行分析:

  1. 在pcntl_fork出建立子進程後,子進程執行功能代碼,父進程繼續遞增任務id,建立下一個任務進程;
  2. 經過pcntl_wait等待有子進程執行完畢退出後,再新建立進程,實現進程總數的控制;
  3. 在主進程完成建立後,經過break退出循環。此時可能有子進程繼續執行。

相關函數:

pcntl_fork

在當前進程當前位置產生分支(子進程)。成功時,在父進程執行線程內返回產生的子進程的PID,在子進程執行線程內返回0。失敗時,在 父進程上下文返回-1,不會建立子進程,而且會引起一個PHP錯誤。

pcntl_wait

等待或返回fork的子進程狀態。wait函數颳起當前進程的執行直到一個子進程退出或接收到一個信號要求中斷當前進程或調用一個信號處理函數。 若是一個子進程在調用此函數時已經退出(俗稱殭屍進程),此函數馬上返回。子進程使用的全部系統資源將 被釋放。

其餘:

1.殭屍進程及孤兒進程的問題code

部分殭屍進程被pcntl_wait獲取狀態並釋放資源,未接管的進程在主進程退出後成爲孤兒進程。孤兒進程被init進程收養,完成wait的狀態獲取和資源釋放。進程

相關文章
相關標籤/搜索