PHP進(jìn)程通信基礎(chǔ)之信號
使用信號通信??梢允褂胟ill -l 來查看當(dāng)前系統(tǒng)的信號類型。
每個(gè)信號所代表的的詳細(xì)含義,請查看我的這篇文章:http://www.dbjr.com.cn/article/106040.htm
使用信號的時(shí)候可以通過php --version 來查看當(dāng)前PHP的版本。已決定使用哪種方式來進(jìn)行進(jìn)程間的信號通信。
[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 函數(shù) 需要PHP 版本(PHP 5 >= 5.3.0, PHP 7)
如果PHP版本小于5.3.一些大公司可能會低于這個(gè)版本。這個(gè)時(shí)候會使用 declare(ticks=1),意思為每執(zhí)行一條低級指令,
就會去檢測是否出現(xiàn)該信號。詳細(xì)的介紹可以查看 http://www.dbjr.com.cn/article/48340.htm
官網(wǎng)解釋如下:Tick(時(shí)鐘周期)是一個(gè)在 declare 代碼段中解釋器每執(zhí)行 N 條可計(jì)時(shí)的低級語句就會發(fā)生的事件。N 的值是在 declare 中的 directive 部分用 ticks=N 來指定的。
那么什么是低級語句呢:如下代碼所示:
for ($i = 0; $i < 3; $i++) { echo $i.PHP_EOL; }
那么這個(gè)for 循環(huán)中就含有三條低級指令。每輸出一條$i。就會去檢測下是否發(fā)生了已注冊的事件,可想而知,這樣效率是比較低的。所以如果檢測到自己的PHP大于等于5.3 。就使用pcntl_singal_dispath 來進(jìn)行信號派送。
主進(jìn)程在啟動的時(shí)候注冊一些信號處理函數(shù)。
/** * @param $signal 信號 */ function signalHandal($signal) { switch ($signal) { case SIGINT: //do something break; case SIGHUP: //do something break; default : //do something break; } }
然后將信號處理器與信號處理函數(shù)綁定:
//根據(jù)不同的信號,安裝不同的信號處理器 pcntl_signal(SIGINT, 'signalHandal'); pcntl_signal(SIGHUP, 'signalHandal'); pcntl_signal(SIGUSR1, 'signalHandla');
在子進(jìn)程監(jiān)聽信號,如果出現(xiàn)該信號,就調(diào)用預(yù)安裝的信號處理函數(shù)
//分配信號。 pcntl_signal_dispatch($signal);
我們來整理下思路:
1、定義信號發(fā)生所需要處理事件的函數(shù)
2、將信號和信號處理函數(shù)綁定,稱為信號安裝。
3、信號監(jiān)聽或者分發(fā),出現(xiàn)信號調(diào)用已安裝的信號。
理解好上面的信號概念,我們來看一個(gè)demo:
<?php $parentpid = posix_getpid(); echo "parent progress pid:{$parentpid}\n"; //定義一個(gè)信號處理函數(shù) function sighandler($signal) { if ($signal == SIGINT) { $pid = getmypid(); exit("{$pid} process, Killed!".PHP_EOL); } } //php version < 5.3 .每執(zhí)行一條低級指令,就檢查一次是否出現(xiàn)該信號。效率損耗很大。 //declare(ticks=1); $child_list = []; //注冊一個(gè)信號處理器。當(dāng)發(fā)出該信號的時(shí)候?qū)φ{(diào)用已定義的函數(shù) pcntl_signal(SIGINT, 'sighandler'); for($i = 0; $i < 3; $i++) { $pid = pcntl_fork(); if ($pid == 0) { //子進(jìn)程 while (true) { //調(diào)用已安裝的信號信號處理器,為了檢測是否有新的信號等待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;
相關(guān)文章
php中g(shù)etservbyport與getservbyname函數(shù)用法實(shí)例
這篇文章主要介紹了php中g(shù)etservbyport與getservbyname函數(shù)用法,以實(shí)例形式分析了getservbyport與getservbyname函數(shù)獲取server端的端口等信息的方法,需要的朋友可以參考下2014-11-11php實(shí)現(xiàn)用于刪除整個(gè)目錄的遞歸函數(shù)
這篇文章主要介紹了php實(shí)現(xiàn)用于刪除整個(gè)目錄的遞歸函數(shù),涉及php遞歸算法與目錄操作技巧,需要的朋友可以參考下2015-03-03PHP將HTML轉(zhuǎn)換成文本的實(shí)現(xiàn)代碼
這篇文章主要介紹了PHP將HTML轉(zhuǎn)換成文本的實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-01-01PHP安全技術(shù)之 實(shí)現(xiàn)php基本安全
php開發(fā)過程中,需要注意的一些安全小細(xì)節(jié),屏蔽錯(cuò)誤提示,多考慮下安全問題。2010-09-09