進程間通訊(IPC)介紹html
php高級應用之進程控制及進程間通信 workman 做者發佈app
-- System V IPC: sysvmsg 消息隊列 sysvsem 信號量 sysvshm 共享內存 -- BSD IPC socket(stream) -- POSIX IPC posix 信號量 posix 共享內存 posix 消息隊列
php ftok 函數做用解析socket
解決進程間通訊問題ui
發送方(send.php
).net
$key = 1; $msg = '發送方發送的消息'; $q = msg_get_queue($key); $send = msg_send($q , 1 , $msg , true , true); if ($send) { echo '消息發送成功' . PHP_EOL; } else { echo '消息發送失敗' . PHP_EOL; }
接收方(receive.php
)code
$key = 1; $q = msg_get_queue($key); /** * 第二個參數解釋: < 0 ,小於該絕對值的最小類型隊列上的第一條記錄 例如我設置了 -5,絕對值 5 該消息隊列的消息類型有 2 3 4 5 6 7 則返回類型爲 2 的消息隊列上的第一條記錄 0 則獲取隊列第一條消息(無論消息類型,標識符) 1 獲取設置類型下的第一條消息 第三個參數必須是個變量!(坑爹的貨!) */ msg_receive($q , 1 , $msg_type , 1024 , $msg , true , MSG_NOERROR , $error_code);
無權限訪問htm
有可能你會碰到訪問無權限訪問隊列的狀況。那是由於你的代碼長這樣。我也忘了是怎樣修復的,後面自動好了。blog
接受不到消息
消息隊列經過指定 key
而被建立後,任意一方銷燬了該隊列,都會致使其餘發送 或 接收方失敗。
注意了:解決進程間同步問題。
場景:進程 A 、B、C,B 中代碼段 y 要用到 A 中代碼段 x 的結果。C 中代碼段 m 要用到 B 中代碼段 y 的結果。
$key = ftok(__FILE__ , 1); $shm = shm_attach($key); create(3 , [ // 進程 A function($index) use($key , $shm){ $sem_id = sem_get($key); // 獲取信號量!(其餘相同獲取該信號量的進程等待,直到該信號量被釋放爲止) sem_acquire($sem_id); // x 處理語句 shm_put_var($shm , 1 , 10); $wait = 3; $count = 1; while ($count >= $wait) { echo '進程 A 等待處理' . $count++ . 's' . PHP_EOL; sleep(1); } // 3s 後釋放信號量 sem_release($shm); } , // 進程 B function($index) use($key , $shm){ $sem_id = sem_get($key); // 獲取信號量!(其餘相同獲取該信號量的進程等待,直到該信號量被釋放爲止) sem_acquire($sem_id); // x 處理語句返回結果 $x = shm_get_var($shm , 1); $y = $x + 11; shm_put_var($shm , 2 , $y); $wait = 5; $count = 1; while ($count >= $wait) { echo '進程 B 等待處理' . $count++ . 's' . PHP_EOL; sleep(1); } // 5s 後釋放信號量 sem_release($shm); } , // 進程 C function($index) use($key , $shm){ $sem_id = sem_get($key); // 獲取信號量!(其餘相同獲取該信號量的進程等待,直到該信號量被釋放爲止) sem_acquire($sem_id); // x 處理語句返回結果 $y = shm_get_var($shm , 2); $c = $x + 12; echo '獲取到結果:' . $c; // 刪除共享內存段 sem_remove($shm); } , ];
解釋:A 首先獲取到信號量,而後等待 3s 後釋放,期間 B、C在調用 sem_acquire
後阻塞,直到獲取到該信號量爲止。A 釋放信號量後,B 現獲取,而後阻塞 5s 釋放,最後 C 獲取,執行。完成了進程間同步問題!此外進程間通訊採用的方式是共享內存。