日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

php pcntl 进程池_PHP 进程池与轮询调度算法实现多任务的示例代码

發(fā)布時間:2025/3/20 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php pcntl 进程池_PHP 进程池与轮询调度算法实现多任务的示例代码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

phper 請了解進程調(diào)度策略,CPU 時間片,進程控制【創(chuàng)建,銷毀,回收,進程信號】與及進程運行流程和基本的進程組,信號中斷原理,以及進程之間的關系。

關于進程的更多內(nèi)容可參考本人前面擼過的文章或是百度了解。

進程的通信:

匿名管道,命名管道,消息隊列,內(nèi)存共享,socketpair 請自行擼代碼測試哦

進程的調(diào)度算法:

輪詢,隨機分發(fā),計分板等策略或是搞個優(yōu)先極或是隊列,或是堆棧等基本的算法【自己去發(fā)揮哦】

進程池:

擼過 tcp 的話應該知道要能處理多個客戶端,就得用 IO 復用技術【事件多路分發(fā)器】或是多進程以及多線程,每來一個客戶端就 fork 一個進程或是線程,那樣的話上下文切換成本特別高,所以咱們先創(chuàng)建好一組進程【進程池】,等客戶端連接上來的時候,通過某種算法【我們用的輪詢】來選擇某個進程投遞任務來干活,這樣的話就不用創(chuàng)建又銷毀來回折騰了,提升它的效率。下面是 PHP 代碼版本的實現(xiàn)

/**

* Created by PhpStorm.

* User: 1655664358@qq.com

* Date: 2019/1/12

* Time: 16:18

*/

$flag = 1;

class process

{

public $pid;

public $name;

public $file;

public $num;

}

class instance

{

public $processIdx;

public $proc = [];

public $processNum;

}

function sigHandler($sigNo)

{

global $flag;

$flag = 0;

echo "信號中斷處理".PHP_EOL;

}

function processPool(instance &$instance,$num)

{

if (!$instance||$num==0){

fprintf(STDERR,"%s","參數(shù)錯誤");

return 1;

}

$instance->processIdx = 0;

$instance->processNum = $num;

pcntl_signal(SIGINT,'sigHandler');

pcntl_signal(SIGTERM,'sigHandler');

$process = new process();

for ($i=1;$i<=$num;$i++){

$instance->proc[$i] = clone $process;

$instance->proc[$i]->file = $i;

$instance->proc[$i]->pid = pcntl_fork();

$instance->processIdx = $i;

if ($instance->proc[$i]->pid<0){

exit("進程創(chuàng)建失敗");

}

else if ($instance->proc[$i]->pid>0){

//nothing

continue;

}else{

worker($instance);

}

}

master($instance);

$exitProcess= [];

while (1){

for ($i=1;$i<=$num;$i++){

//非阻塞方式回收子進程

pcntl_waitpid($instance->proc[$i]->pid,$status,WNOHANG);

if ($status){

$exitProcess[] = $instance->proc[$i]->pid;

fwrite(STDOUT,"worker#".$instance->proc[$i]->pid."-".$status,30);

}

}

if (count($exitProcess)==$instance->processNum){

exit(0);

}

usleep(1000);

}

}

//簡單的輪詢算法 自己可以用隊列,隨機,鏈表,棧鏈,二叉樹啥的折騰

function roundRobin(&$instance,$roll)

{

/** @var instance $instance */

return $instance->proc[$roll%$instance->processNum+1];

}

function master(&$instance)

{

/** @var instance $instance */

fprintf(STDOUT,"master 進程 %d\n",$instance->processIdx);

global $flag;

$roll = 0;

while ($flag){

pcntl_signal_dispatch();

/** @var process $process */

$process = roundRobin($instance,$roll++);

echo "輪詢的進程:".$process->pid.PHP_EOL;

$file = $process->file;

posix_mkfifo($file,0666);

$fd = fopen($file,"w");

fwrite($fd,"hi",2);

sleep(1);

}

for ($i=1;$i<=$instance->processNum;$i++){

posix_kill($instance->proc[$i]->pid,9);

}

fprintf(STDOUT,"master shutdown %d\n",$instance->processIdx);

}

function getProcess(&$instance)

{

/** @var instance $instance */

return $instance->proc[$instance->processIdx];

}

function worker(&$instance)

{

/** @var process $process */

$process = getProcess($instance);

while (1){

$file = $process->file;

posix_mkfifo($file,0666);

$fd = fopen($file,"r");

$content = fread($fd,10);

fprintf(STDOUT,"worker#%d讀取的內(nèi)容:%s file=%d\n",posix_getpid(),$content,$file);

}

exit(0);

}

$instance = new instance();

processPool($instance,5);

效果

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

總結

以上是生活随笔為你收集整理的php pcntl 进程池_PHP 进程池与轮询调度算法实现多任务的示例代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。