關於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:
複製代碼 代碼如下:<?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);
?>
這段代碼的運行結果如下: 複製代碼 代碼如下: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!”字串
下面列舉一下範例程式碼中的主要函數: 複製代碼 代碼如下: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用於銷毀一個隊列。
範例程式碼_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等進行處理序間通訊的方法。