首頁 >後端開發 >php教程 >php多行程執行任務的說明

php多行程執行任務的說明

不言
不言原創
2018-07-06 11:21:302350瀏覽

這篇文章主要介紹了關於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.殭屍行程及孤兒行程的問題

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

以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!

相關推薦:

php的快速排序的程式碼

#Laravel5.5執行表遷移指令出現表為空的解決方案

PHP變數之作用域、global、static等關鍵字

以上是php多行程執行任務的說明的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn