PHP下操做Linux消息隊列完成進程間通訊的方法

來源:http://www.jb51.net/article/24353.htmphp

關於Linux系統進程通訊的概念及實現可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/ 
  關於Linux系統消息隊列的概念及實現可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/
  PHP的sysvmsg模塊是對Linux系統支持的System V IPC中的System V消息隊列函數族的封裝。咱們須要利用sysvmsg模塊提供的函數來進進程間通訊。先來看一段示例代碼_1: linux

複製代碼代碼以下:數組


?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); 
//向消息隊列中寫 
msg_send($message_queue, 1, "Hello,World!"); 
$message_queue_status = msg_stat_queue($message_queue); 
print_r($message_queue_status); 
//從消息隊列中讀 
msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT); 
print_r($message."\r\n"); 
msg_remove_queue($message_queue); 
?異步


這段代碼的運行結果以下: socket

複製代碼代碼以下:ide


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! 函數


能夠看到已成功從消息隊列中讀取「Hello,World!」字符串 
  下面列舉一下示例代碼中的主要函數: ui

複製代碼代碼以下:this


ftok ( string $pathname , string $proj ) 
手冊上給出的解釋是:Convert a pathname and a project identifier to a System V IPC key。這個函數返回的鍵值惟一對應linux系統中一個消息隊列。在得到消息隊列的引用以前都須要調用這個函數。 
msg_get_queue ( int $key [, int $perms ] ) 
msg_get_queue()會根據傳入的鍵值返回一個消息隊列的引用。若是linux系統中沒有消息隊列與鍵值對應,msg_get_queue()將會建立一個新的消息隊列。函數的第二個參數須要傳入一個int值,做爲新建立的消息隊列的權限值,默認爲0666。這個權限值與linux命令chmod中使用的數值是同一個意思,由於在linux系統中一切皆是文件。 
msg_send ( resource $queue , int $msgtype , mixed $message [, bool $serialize [, bool $blocking [, int &$errorcode ]]] ) 
顧名思義,該函數用來向消息隊列中寫數據。 
msg_stat_queue ( resource $queue ) 
這個函數會返回消息隊列的元數據。消息隊列元數據中的信息很完整,包括了消息隊列中待讀取的消息數、最後讀寫隊列的進程ID等。示例代碼在第8行調用該函數返回的數組中隊列中待讀取的消息數msg_qnum值爲0。 
msg_receive ( resource $queue , int $desiredmsgtype , int &$msgtype , int $maxsize , mixed &$message [, bool $unserialize [, int $flags [, int &$errorcode ]]] ) 
msg_receive用於讀取消息隊列中的數據。 
msg_remove_queue ( resource $queue ) 
msg_remove_queue用於銷燬一個隊列。 .net


示例代碼_1只是展現了PHP操做消息隊列函數的應用。下面的代碼具體描述了進程間通訊的場景 

複製代碼代碼以下:


?php 
$message_queue_key = ftok(__FILE__, 'a'); 
$message_queue = msg_get_queue($message_queue_key, 0666); 
$pids = array(); 
for ($i = 0; $i < 5; $i++) { 
//建立子進程 
$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; 
//須要判斷隊列是否爲空,若是爲空就退出 
//break; 
} while(true) 
?


運行結果爲: 

複製代碼代碼以下:


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 

這段程序每次的運行結果都會不一樣,這正說明了多進程的異步性。從結果也能看出消息隊列FIFO特性。  以上即是我研究的一點心得。接下來將會繼續研究PHP利用信號、socket等進行進程間通訊的方法。

相關文章
相關標籤/搜索