《PHP實例:PHP進程通信基礎之信號》要點:
本文介紹了PHP實例:PHP進程通信基礎之信號,希望對您有用。如果有疑問,可以聯系我們。
使用信號通信.可以使用kill -l 來查看當前系統的信號類型.
每個信號所代表的的詳細含義,請查看我的這篇文章:/article/106040.htm
使用信號的時候可以通過php --version 來查看當前PHP的版本.已決定使用哪種方式來進行進程間的信號通信.PHP教程
[root@roverliang ipc]# php --version PHP 5.6.24 (cli) (built: Aug 15 2016 19:14:02) Copyright (c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
使用pcntl_signal_dispatch 函數 需要PHP 版本(PHP 5 >= 5.3.0, PHP 7)
PHP教程
如果PHP版本小于5.3.一些大公司可能會低于這個版本.這個時候會使用 declare(ticks=1),意思為每執行一條低級指令,
就會去檢測是否出現該信號.詳細的介紹可以查看 /article/48340.htmPHP教程
官網解釋如下:Tick(時鐘周期)是一個在 declare 代碼段中解釋器每執行 N 條可計時的低級語句就會發生的事件.N 的值是在 declare 中的 directive 部分用 ticks=N 來指定的.PHP教程
那么什么是低級語句呢:如下代碼所示:PHP教程
for ($i = 0; $i < 3; $i++) { echo $i.PHP_EOL; }
那么這個for 循環中就含有三條低級指令.每輸出一條$i.就會去檢測下是否發生了已注冊的事件,可想而知,這樣效率是比較低的.所以如果檢測到自己的PHP大于等于5.3 .就使用pcntl_singal_dispath 來進行信號派送.PHP教程
主進程在啟動的時候注冊一些信號處理函數.PHP教程
/** * @param $signal 信號 */ function signalHandal($signal) { switch ($signal) { case SIGINT: //do something break; case SIGHUP: //do something break; default : //do something break; } }
然后將信號處理器與信號處理函數綁定:PHP教程
//根據不同的信號,安裝不同的信號處理器 pcntl_signal(SIGINT, 'signalHandal'); pcntl_signal(SIGHUP, 'signalHandal'); pcntl_signal(SIGUSR1, 'signalHandla');
在子進程監聽信號,如果出現該信號,就調用預安裝的信號處理函數PHP教程
//分配信號. pcntl_signal_dispatch($signal);
我們來整理下思路:
1、定義信號發生所需要處理事件的函數
2、將信號和信號處理函數綁定,稱為信號安裝.
3、信號監聽或者分發,出現信號調用已安裝的信號.PHP教程
理解好上面的信號概念,我們來看一個demo:PHP教程
<?php $parentpid = posix_getpid(); echo "parent progress pid:{$parentpid}\n"; //定義一個信號處理函數 function sighandler($signal) { if ($signal == SIGINT) { $pid = getmypid(); exit("{$pid} process, Killed!".PHP_EOL); } } //php version < 5.3 .每執行一條低級指令,就檢查一次是否出現該信號.效率損耗很大. //declare(ticks=1); $child_list = []; //注冊一個信號處理器.當發出該信號的時候對調用已定義的函數 pcntl_signal(SIGINT, 'sighandler'); for($i = 0; $i < 3; $i++) { $pid = pcntl_fork(); if ($pid == 0) { //子進程 while (true) { //調用已安裝的信號信號處理器,為了檢測是否有新的信號等待dispatching pcntl_signal_dispatch(); echo "I am child: ".getmypid(). " and i am running !".PHP_EOL; sleep(rand(1,3)); } } elseif($pid > 0) { $child_list[] = $pid; } else { die('fork fail!'.PHP_EOL); } } sleep(5); foreach ($child_list as $key => $pid) { posix_kill($pid, SIGINT); } sleep(2); echo "{$parentpid} parent is end".PHP_EOL;
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/1724.html