進(jìn)程是一個(gè)具有獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合的一次運(yùn)行活動(dòng)。換句話說(shuō)就是,在系統(tǒng)調(diào)度多個(gè)cpu的時(shí)候,一個(gè)程序的基本單元。進(jìn)程對(duì)于大多數(shù)的語(yǔ)言都不是一個(gè)陌生的概念,作為”世界上最好的語(yǔ)言php”當(dāng)然也例外。
通常linux中的進(jìn)程通信方式有:消息隊(duì)列、信號(hào)量、共享內(nèi)存、信號(hào)、管道、socket。
向消息隊(duì)列發(fā)送數(shù)據(jù)和獲取數(shù)據(jù)的測(cè)試
<?php
$key=ftok(__file__,'a');
//獲取消息隊(duì)列
$queue=msg_get_queue($key,0666);
//發(fā)送消息
//msg_send($queue, 1, hello, 1);
//接收消息,如果接收不到會(huì)阻塞
msg_receive($queue, 1, $message_type, 1024, $message1);
//移除消息
//msg_remove_queue($queue);
//var_dump($message1);<?php
/
* 這段代碼模擬了一個(gè)日常的任務(wù)。
* 第一個(gè)父進(jìn)程產(chǎn)生了一個(gè)子進(jìn)程。子進(jìn)程又作為父進(jìn)程,產(chǎn)生10個(gè)子進(jìn)程。
* 可以簡(jiǎn)化為a -> b -> c,d,e... 等進(jìn)程。
* 作為a來(lái)說(shuō),只需要生產(chǎn)任務(wù),然后交給b 來(lái)處理。b 則會(huì)將任務(wù)分配給10個(gè)子進(jìn)程來(lái)進(jìn)行處理。
*
*/
//設(shè)定腳本永不超時(shí)
set_time_limit(0);
$ftok = ftok(__file__, 'a');
$msg_queue = msg_get_queue($ftok);
$pidarr = [];
//產(chǎn)生子進(jìn)程
$pid = pcntl_fork();
if ($pid) {
//父進(jìn)程模擬生成一個(gè)特大的數(shù)組。
$arr = range(1,100000);
//將任務(wù)放進(jìn)隊(duì)里,讓多個(gè)子進(jìn)程并行處理
foreach ($arr as $val) {
$status = msg_send($msg_queue,1, $val);
usleep(1000);
}
$pidarr[] = $pid;
msg_remove_queue($msg_queue);
} else {
//子進(jìn)程收到任務(wù)后,fork10個(gè)子進(jìn)程來(lái)處理任務(wù)。
for ($i =0; $i<10; $i++) {
$childpid = pcntl_fork();
if ($childpid) {
$pidarr[] = $childpid; //收集子進(jìn)程processid
} else {
while (true) {
msg_receive($msg_queue, 0, $msg_type, 1024, $message);
if (!$message) exit(0);
echo $message.php_eol;
usleep(1000);
}
}
}
}
//防止主進(jìn)程先于子進(jìn)程退出,形成僵尸進(jìn)程
while (count($pidarr) > 0) {
foreach ($pidarr as $key => $pid) {
$status = pcntl_waitpid($pid, $status);
if ($status == -1 || $status > 0) {
unset($pidarr[$key]);
}
}
sleep(1);
}