龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > php编程 >

PHP多进程编程实例(2)

时间:2014-10-17 11:52来源:网络整理 作者:网络 点击:
分享到:
刚刚有man ps么?一般我习惯用ps aux加上grep命令来查找运行着的后台进程。其中有一列STAT,标识了每个进程的运行状态。这里,我们关注状态Z:僵尸(Zo

刚刚有man ps么?一般我习惯用ps aux加上grep命令来查找运行着的后台进程。其中有一列STAT,标识了每个进程的运行状态。这里,我们关注状态Z:僵尸(Zombie)。当子进程比父进程先退出,而父进程没对其做任何处理的时候,子进程将会变成僵尸进程。Oops,又跟火影里的影分身不一样了。鸣人的影分身被干死了以后就自动消失了,但是这里的子进程分身死了话还留着一个空壳在,直到父进程回收它。僵尸进程虽然不占什么内存,但是很碍眼,院子里一堆躺着的僵尸怎么都觉得怪怪的。(别忘了它们还占用着PID)

一般来说,在父进程结束之前回收挂掉的子进程就可以了。在pcntl扩展里面有一个pcntl_wait()函数,它会将父进程挂起,直到有一个子进程退出为止。如果有一个子进程变成了僵尸的话,它会立即返回。所有的子进程都要回收,所以多等等也没关系啦!

3.4. 父进程先挂了

如果父进程先挂了怎么办?会发生什么?什么也不会发生,子进程依旧还在运行。但是这个时候,子进程会被交给1号进程,1号进程成为了这些子进程的继父。1号进程会很好地处理这些进程的资源,当它们结束时1号进程会自动回收资源。所以,另一种处理僵尸进程的临时办法是关闭它们的父进程。

4. 信号

一般多进程的事儿讲到上面就完了,可是信号在系统中确实是一个非常重要的东西。信号就是信号灯,点亮一个信号灯,程序就会做出反应。这个你一定用过,比如说在终端下运行某个程序,等了半天也没什么反应,可能你会按 Ctrl+C 来关闭这个程序。实际上,这里就是通过键盘向程序发送了一个中断的信号:SIGINT。有时候进程失去响应了还会执行kill [PID]命令,未加任何其他参数的话,程序会接收到一个SIGTERM信号。程序收到上面两个信号的时候,默认都会结束执行,那么是否有可能改变这种默认行为呢?必须能啊!

4.1. 注册信号

人是活的程序也是活的,只不过程序需要遵循人制定的规则来运行。现在开始给信号重新设定规则,这里用到的函数是pcntl_signal()(继续之前为啥不先查查PHP手册呢?)。下面这段程序将给SIGINT重新定义行为,注意看好:

复制代码 代码如下:

// 定义一个处理器,接收到SIGINT信号后只输出一行信息
function signalHandler($signal) {
    if ($signal == SIGINT) {
        echo 'signal received' . PHP_EOL;
    }
}
// 信号注册:当接收到SIGINT信号时,调用signalHandler()函数
pcntl_signal(SIGINT, 'signalHandler');
while (true) {
    sleep(1);
    // do something
    pcntl_signal_dispatch(); // 接收到信号时,调用注册的signalHandler()
}

执行一下,随时按下 Ctrl+C 看看会发生什么事。

4.2. 信号分发

精彩图集

赞助商链接