PHP下操作Linux消息隊(duì)列完成進(jìn)程間通信的方法
更新時(shí)間:2010年07月24日 01:13:05 作者:
當(dāng)我們開發(fā)的系統(tǒng)需要使用多進(jìn)程方式運(yùn)行時(shí),進(jìn)程間通信便成了至關(guān)重要的環(huán)節(jié)。消息隊(duì)列(message queue)是Linux系統(tǒng)進(jìn)程間通信的一種方式。
關(guān)于Linux系統(tǒng)進(jìn)程通信的概念及實(shí)現(xiàn)可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/
關(guān)于Linux系統(tǒng)消息隊(duì)列的概念及實(shí)現(xiàn)可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/
PHP的sysvmsg模塊是對(duì)Linux系統(tǒng)支持的System V IPC中的System V消息隊(duì)列函數(shù)族的封裝。我們需要利用sysvmsg模塊提供的函數(shù)來(lái)進(jìn)進(jìn)程間通信。先來(lái)看一段示例代碼_1:
<?php
$message_queue_key = ftok(__FILE__, 'a');
$message_queue = msg_get_queue($message_queue_key, 0666);
var_dump($message_queue);
$message_queue_status = msg_stat_queue($message_queue);
print_r($message_queue_status);
//向消息隊(duì)列中寫
msg_send($message_queue, 1, "Hello,World!");
$message_queue_status = msg_stat_queue($message_queue);
print_r($message_queue_status);
//從消息隊(duì)列中讀
msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT);
print_r($message."\r\n");
msg_remove_queue($message_queue);
?>
這段代碼的運(yùn)行結(jié)果如下:
resource(4) of type (sysvmsg queue)
Array
(
[msg_perm.uid] => 1000
[msg_perm.gid] => 1000
[msg_perm.mode] => 438
[msg_stime] => 0
[msg_rtime] => 0
[msg_ctime] => 1279849495
[msg_qnum] => 0
[msg_qbytes] => 16384
[msg_lspid] => 0
[msg_lrpid] => 0
)
Array
(
[msg_perm.uid] => 1000
[msg_perm.gid] => 1000
[msg_perm.mode] => 438
[msg_stime] => 1279849495
[msg_rtime] => 0
[msg_ctime] => 1279849495
[msg_qnum] => 1
[msg_qbytes] => 16384
[msg_lspid] => 2184
[msg_lrpid] => 0
)
Hello,World!
可以看到已成功從消息隊(duì)列中讀取“Hello,World!”字符串
下面列舉一下示例代碼中的主要函數(shù):
ftok ( string $pathname , string $proj )
手冊(cè)上給出的解釋是:Convert a pathname and a project identifier to a System V IPC key。這個(gè)函數(shù)返回的鍵值唯一對(duì)應(yīng)linux系統(tǒng)中一個(gè)消息隊(duì)列。在獲得消息隊(duì)列的引用之前都需要調(diào)用這個(gè)函數(shù)。
msg_get_queue ( int $key [, int $perms ] )
msg_get_queue()會(huì)根據(jù)傳入的鍵值返回一個(gè)消息隊(duì)列的引用。如果linux系統(tǒng)中沒(méi)有消息隊(duì)列與鍵值對(duì)應(yīng),msg_get_queue()將會(huì)創(chuàng)建一個(gè)新的消息隊(duì)列。函數(shù)的第二個(gè)參數(shù)需要傳入一個(gè)int值,作為新創(chuàng)建的消息隊(duì)列的權(quán)限值,默認(rèn)為0666。這個(gè)權(quán)限值與linux命令chmod中使用的數(shù)值是同一個(gè)意思,因?yàn)樵趌inux系統(tǒng)中一切皆是文件。
msg_send ( resource $queue , int $msgtype , mixed $message [, bool $serialize [, bool $blocking [, int &$errorcode ]]] )
顧名思義,該函數(shù)用來(lái)向消息隊(duì)列中寫數(shù)據(jù)。
msg_stat_queue ( resource $queue )
這個(gè)函數(shù)會(huì)返回消息隊(duì)列的元數(shù)據(jù)。消息隊(duì)列元數(shù)據(jù)中的信息很完整,包括了消息隊(duì)列中待讀取的消息數(shù)、最后讀寫隊(duì)列的進(jìn)程ID等。示例代碼在第8行調(diào)用該函數(shù)返回的數(shù)組中隊(duì)列中待讀取的消息數(shù)msg_qnum值為0。
msg_receive ( resource $queue , int $desiredmsgtype , int &$msgtype , int $maxsize , mixed &$message [, bool $unserialize [, int $flags [, int &$errorcode ]]] )
msg_receive用于讀取消息隊(duì)列中的數(shù)據(jù)。
msg_remove_queue ( resource $queue )
msg_remove_queue用于銷毀一個(gè)隊(duì)列。
示例代碼_1只是展示了PHP操作消息隊(duì)列函數(shù)的應(yīng)用。下面的代碼具體描述了進(jìn)程間通信的場(chǎng)景
<?php
$message_queue_key = ftok(__FILE__, 'a');
$message_queue = msg_get_queue($message_queue_key, 0666);
$pids = array();
for ($i = 0; $i < 5; $i++) {
//創(chuàng)建子進(jìn)程
$pids[$i] = pcntl_fork();
if ($pids[$i]) {
echo "No.$i child process was created, the pid is $pids[$i]\r\n";
} elseif ($pids[$i] == 0) {
$pid = posix_getpid();
echo "process.$pid is writing now\r\n";
msg_send($message_queue, 1, "this is process.$pid's data\r\n");
posix_kill($pid, SIGTERM);
}
}
do {
msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT);
echo $message;
//需要判斷隊(duì)列是否為空,如果為空就退出
//break;
} while(true)
?>
運(yùn)行結(jié)果為:
No.0 child process was created, the pid is 5249
No.1 child process was created, the pid is 5250
No.2 child process was created, the pid is 5251
No.3 child process was created, the pid is 5252
No.4 child process was created, the pid is 5253
process.5251 is writing now
this is process.5251's data
process.5253 is writing now
process.5252 is writing now
process.5250 is writing now
this is process.5253's data
this is process.5252's data
this is process.5250's data
process.5249 is writing now
this is process.5249's data
這段程序每次的運(yùn)行結(jié)果都會(huì)不同,這正說(shuō)明了多進(jìn)程的異步性。從結(jié)果也能看出消息隊(duì)列FIFO特性。
以上便是我研究的一點(diǎn)心得。接下來(lái)將會(huì)繼續(xù)研究PHP利用信號(hào)、socket等進(jìn)行進(jìn)程間通信的方法。
關(guān)于Linux系統(tǒng)消息隊(duì)列的概念及實(shí)現(xiàn)可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/
PHP的sysvmsg模塊是對(duì)Linux系統(tǒng)支持的System V IPC中的System V消息隊(duì)列函數(shù)族的封裝。我們需要利用sysvmsg模塊提供的函數(shù)來(lái)進(jìn)進(jìn)程間通信。先來(lái)看一段示例代碼_1:
復(fù)制代碼 代碼如下:
<?php
$message_queue_key = ftok(__FILE__, 'a');
$message_queue = msg_get_queue($message_queue_key, 0666);
var_dump($message_queue);
$message_queue_status = msg_stat_queue($message_queue);
print_r($message_queue_status);
//向消息隊(duì)列中寫
msg_send($message_queue, 1, "Hello,World!");
$message_queue_status = msg_stat_queue($message_queue);
print_r($message_queue_status);
//從消息隊(duì)列中讀
msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT);
print_r($message."\r\n");
msg_remove_queue($message_queue);
?>
這段代碼的運(yùn)行結(jié)果如下:
復(fù)制代碼 代碼如下:
resource(4) of type (sysvmsg queue)
Array
(
[msg_perm.uid] => 1000
[msg_perm.gid] => 1000
[msg_perm.mode] => 438
[msg_stime] => 0
[msg_rtime] => 0
[msg_ctime] => 1279849495
[msg_qnum] => 0
[msg_qbytes] => 16384
[msg_lspid] => 0
[msg_lrpid] => 0
)
Array
(
[msg_perm.uid] => 1000
[msg_perm.gid] => 1000
[msg_perm.mode] => 438
[msg_stime] => 1279849495
[msg_rtime] => 0
[msg_ctime] => 1279849495
[msg_qnum] => 1
[msg_qbytes] => 16384
[msg_lspid] => 2184
[msg_lrpid] => 0
)
Hello,World!
可以看到已成功從消息隊(duì)列中讀取“Hello,World!”字符串
下面列舉一下示例代碼中的主要函數(shù):
復(fù)制代碼 代碼如下:
ftok ( string $pathname , string $proj )
手冊(cè)上給出的解釋是:Convert a pathname and a project identifier to a System V IPC key。這個(gè)函數(shù)返回的鍵值唯一對(duì)應(yīng)linux系統(tǒng)中一個(gè)消息隊(duì)列。在獲得消息隊(duì)列的引用之前都需要調(diào)用這個(gè)函數(shù)。
msg_get_queue ( int $key [, int $perms ] )
msg_get_queue()會(huì)根據(jù)傳入的鍵值返回一個(gè)消息隊(duì)列的引用。如果linux系統(tǒng)中沒(méi)有消息隊(duì)列與鍵值對(duì)應(yīng),msg_get_queue()將會(huì)創(chuàng)建一個(gè)新的消息隊(duì)列。函數(shù)的第二個(gè)參數(shù)需要傳入一個(gè)int值,作為新創(chuàng)建的消息隊(duì)列的權(quán)限值,默認(rèn)為0666。這個(gè)權(quán)限值與linux命令chmod中使用的數(shù)值是同一個(gè)意思,因?yàn)樵趌inux系統(tǒng)中一切皆是文件。
msg_send ( resource $queue , int $msgtype , mixed $message [, bool $serialize [, bool $blocking [, int &$errorcode ]]] )
顧名思義,該函數(shù)用來(lái)向消息隊(duì)列中寫數(shù)據(jù)。
msg_stat_queue ( resource $queue )
這個(gè)函數(shù)會(huì)返回消息隊(duì)列的元數(shù)據(jù)。消息隊(duì)列元數(shù)據(jù)中的信息很完整,包括了消息隊(duì)列中待讀取的消息數(shù)、最后讀寫隊(duì)列的進(jìn)程ID等。示例代碼在第8行調(diào)用該函數(shù)返回的數(shù)組中隊(duì)列中待讀取的消息數(shù)msg_qnum值為0。
msg_receive ( resource $queue , int $desiredmsgtype , int &$msgtype , int $maxsize , mixed &$message [, bool $unserialize [, int $flags [, int &$errorcode ]]] )
msg_receive用于讀取消息隊(duì)列中的數(shù)據(jù)。
msg_remove_queue ( resource $queue )
msg_remove_queue用于銷毀一個(gè)隊(duì)列。
示例代碼_1只是展示了PHP操作消息隊(duì)列函數(shù)的應(yīng)用。下面的代碼具體描述了進(jìn)程間通信的場(chǎng)景
復(fù)制代碼 代碼如下:
<?php
$message_queue_key = ftok(__FILE__, 'a');
$message_queue = msg_get_queue($message_queue_key, 0666);
$pids = array();
for ($i = 0; $i < 5; $i++) {
//創(chuàng)建子進(jìn)程
$pids[$i] = pcntl_fork();
if ($pids[$i]) {
echo "No.$i child process was created, the pid is $pids[$i]\r\n";
} elseif ($pids[$i] == 0) {
$pid = posix_getpid();
echo "process.$pid is writing now\r\n";
msg_send($message_queue, 1, "this is process.$pid's data\r\n");
posix_kill($pid, SIGTERM);
}
}
do {
msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT);
echo $message;
//需要判斷隊(duì)列是否為空,如果為空就退出
//break;
} while(true)
?>
運(yùn)行結(jié)果為:
復(fù)制代碼 代碼如下:
No.0 child process was created, the pid is 5249
No.1 child process was created, the pid is 5250
No.2 child process was created, the pid is 5251
No.3 child process was created, the pid is 5252
No.4 child process was created, the pid is 5253
process.5251 is writing now
this is process.5251's data
process.5253 is writing now
process.5252 is writing now
process.5250 is writing now
this is process.5253's data
this is process.5252's data
this is process.5250's data
process.5249 is writing now
this is process.5249's data
這段程序每次的運(yùn)行結(jié)果都會(huì)不同,這正說(shuō)明了多進(jìn)程的異步性。從結(jié)果也能看出消息隊(duì)列FIFO特性。
以上便是我研究的一點(diǎn)心得。接下來(lái)將會(huì)繼續(xù)研究PHP利用信號(hào)、socket等進(jìn)行進(jìn)程間通信的方法。
您可能感興趣的文章:
- php實(shí)現(xiàn)的一個(gè)簡(jiǎn)單json rpc框架實(shí)例
- php xml-rpc遠(yuǎn)程調(diào)用
- AMFPHP php遠(yuǎn)程調(diào)用(RPC, Remote Procedure Call)工具 快速入門教程
- php中關(guān)于codeigniter的xmlrpc的類在進(jìn)行數(shù)據(jù)交換時(shí)的類型問(wèn)題
- PHP實(shí)現(xiàn)與java 通信的插件使用教程
- php與java通過(guò)socket通信的實(shí)現(xiàn)代碼
- PHP與Java進(jìn)行通信的實(shí)現(xiàn)方法
- PHP的Socket通信之UDP通信實(shí)例
- PHP 與 js的通信(via ajax,json)
- PHP與Go語(yǔ)言之間的通信詳解
- php中socket通信機(jī)制實(shí)例詳解
- PHP實(shí)現(xiàn)創(chuàng)建一個(gè)RPC服務(wù)操作示例
相關(guān)文章
一個(gè)簡(jiǎn)潔實(shí)用的PHP緩存類完整實(shí)例
這篇文章主要介紹了一個(gè)簡(jiǎn)潔實(shí)用的PHP緩存類完整實(shí)例,緩存的應(yīng)用對(duì)于php大型項(xiàng)目的開發(fā)來(lái)說(shuō)至關(guān)重要,需要的朋友可以參考下2014-07-07php利用iframe實(shí)現(xiàn)無(wú)刷新文件上傳功能的代碼
上傳原理很簡(jiǎn)單就是利用表單的打開方式為iframe的id名,這樣就可以在當(dāng)前頁(yè)面的iframe打來(lái)了,實(shí)現(xiàn)文件上傳,再利用js返回上傳結(jié)果。2011-09-09fleaphp crud操作之findByField函數(shù)的使用方法
fleaphp crud操作之findByField函數(shù)的用法分享,需要的朋友可以參考下。2011-04-04php使用ZipArchive提示Fatal error: Class ZipArchive not found in的
這篇文章主要介紹了php使用ZipArchive提示Fatal error: Class ZipArchive not found in的解決方法,是使用ZipArchive時(shí)經(jīng)常會(huì)遇到的問(wèn)題,需要的朋友可以參考下2014-11-11PHP頁(yè)面跳轉(zhuǎn)操作實(shí)例分析(header方法)
這篇文章主要介紹了PHP頁(yè)面跳轉(zhuǎn)操作,結(jié)合實(shí)例形式對(duì)比分析了HTML跳轉(zhuǎn)與php使用header方法跳轉(zhuǎn)的相關(guān)操作技巧與注意事項(xiàng),并給出了一個(gè)跳轉(zhuǎn)的封裝函數(shù)供大家參考,需要的朋友可以參考下2016-09-09詳談php ip2long 出現(xiàn)負(fù)數(shù)的原因及解決方法
下面小編就為大家?guī)?lái)一篇詳談php ip2long 出現(xiàn)負(fù)數(shù)的原因及解決方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04