PHP多进程编程之僵尸进程问题的理解


Posted in PHP onOctober 15, 2017

PHP多进程编程之僵尸进程问题的理解

使用pcntl_fork函数可以让PHP实现多进程并发或者异步处理的效果:https://3water.com/article/125789.htm

那么问题是我们产生的进程需要去控制,而不能置之不理。最基本的方式就是fork进程和杀死进程。

通过利用pcntl_fork函数,我们已经有了新的子进程,而子进程接下来完成我们需要处理的内容,那么我们就暂且叫做service()吧,而且我们需要很多个service()进行处理,再次参照我们之前的需求,父进程需要一直循环读取配置文件,等待文件发生改变。通过对pcntl_fork的方式,很容易我们就可以写出如下代码:

$res = config();
//kill进程
for($i = 0; $i < $res[sum]; $i++) {
  $pid = pcntl_fork();
  if ($pid == 0) {
    service();
    return;
  }
}

代码中注释的地方我们需要在配置文件中发生改变的时候杀死进程,杀死进程的的方式很简单,可以使用kill命令直接杀死,比如(假设pid为123):

1 kill 123

但是我们发现,使用这个杀死进程的方式并没有真正的把进程杀死,这个子进程被杀死后还占用这个进程的资源,我们成为僵尸进程,僵尸进程是使用kill命令无法杀死的。想要解决这个问题,我们能做的只有两种方式。

1. shutdown

2. 杀死该进程的父进程。

但是这两种方法都不行,因为这个程序的目的是监控常驻在服务器内,服务器不能关闭,并且父进程也不能被干掉。这时候我们看到了官方文档对于fork方法的解释:

pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。

原来有种方式可以防止进程成为僵尸进程,但是,官网给出的代码是这样子的:

$pid = pcntl_fork();
//父进程和子进程都会执行下面代码
if ($pid == -1) {
  //错误处理:创建子进程失败时返回-1.
   die('could not fork');
} else if ($pid) {
   //父进程会得到子进程号,所以这里是父进程执行的逻辑
   pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
} else {
   //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
}

什么意思呢?就是父进程会等待子进程运行,等子进程运行结束之后,才会进行下一步,并且也会消除僵尸进程。但是这里又和我们的需求不符合了,我们的子进程为一个死循环的程序,不断的查找输出,更本没有结束的时候,并且我们需要的是异步处理而不是同步。但是这个方法可以用吗?其实当然可以。

在pcntl_wait的文档中是这么解释这个函数的:

wait函数刮起当前进程的执行直到一个子进程退出或接收到一个信号要求中断当前进程或调用一个信号处理函数。 如果一个子进程在调用此函数时已经退出(俗称僵尸进程),此函数立刻返回。子进程使用的所有系统资源将 被释放。关于wait在您系统上工作的详细规范请查看您系统的wait(2)手册。

我们发现,当这个函数发现子进程成为了僵尸进程就会释放僵尸进程的资源——前提是这个僵尸进程为这个父进程的子进程。那么我们就可以巧妙的利用这个方式让这些僵尸进程释放资源了,所以就有了如下代码:

posix_kill(123, 9);
 pcntl_wait($status);

这样我们先使用kill干掉这个进程,这个进程就不会再运行了,但是这个进程成为了僵尸进程,占用着资源,我们下一句就执行一次pcntl_wait()让这些僵尸进程释放资源,这样,子进程才真正的被终止了,僵尸进程被消除了。

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

PHP 相关文章推荐
用PHP+java实现自动新闻滚动窗口
Oct 09 PHP
信用卡效验程序
Oct 09 PHP
PHP 日常开发小技巧
Sep 23 PHP
php和js如何通过json互相传递数据相关问题探讨
Feb 26 PHP
php页面跳转代码 输入网址跳转到你定义的页面
Mar 28 PHP
php实现在线生成条形码示例分享(条形码生成器)
Dec 30 PHP
php处理restful请求的路由类分享
Feb 27 PHP
php实现扫描二维码根据浏览器类型访问不同下载地址
Oct 15 PHP
php中mkdir()函数的权限问题分析
Sep 24 PHP
网站被恶意镜像怎么办 php一段代码轻松搞定(全面版)
Oct 23 PHP
php如何计算两坐标点之间的距离
Dec 29 PHP
PHP删除数组中特定元素的两种方法
Feb 28 PHP
PHP多进程之pcntl_fork的实例详解
Oct 15 #PHP
详解thinkphp5+swoole实现异步邮件群发(SMTP方式)
Oct 13 #PHP
详解PHP字符串替换str_replace()函数四种用法
Oct 13 #PHP
浅谈PHP接入(第三方登录)QQ登录 OAuth2.0 过程中遇到的坑
Oct 13 #PHP
PHP长网址与短网址的实现方法
Oct 13 #PHP
如何直接访问php实例对象中的private属性详解
Oct 12 #PHP
thinkphp中的多表关联查询的实例详解
Oct 12 #PHP
You might like
php中的观察者模式简单实例
2015/01/20 PHP
php基于dom实现读取图书xml格式数据的方法
2017/02/03 PHP
PHP判断一个数组是另一个数组子集的方法详解
2017/07/31 PHP
PHP7 标准库修改
2021/03/09 PHP
javascript DOM编程实例(智播客学习)
2009/11/23 Javascript
JavaScript 原型与继承说明
2010/06/09 Javascript
JQuery实现倒计时按钮的实现代码
2012/03/23 Javascript
Jquery倒数计时按钮setTimeout的实例代码
2013/07/04 Javascript
浅析JavaScript中的typeof运算符
2013/11/30 Javascript
js 上下左右键控制焦点(示例代码)
2013/12/14 Javascript
JS使用replace()方法和正则表达式进行字符串的搜索与替换实例
2014/04/10 Javascript
js加密解密字符串可自定义密码因子
2014/05/13 Javascript
AngularJS入门教程之模块化操作用法示例
2016/11/02 Javascript
遍历js中对象的属性和值的实例
2016/11/21 Javascript
JavaScript实现网页头部进度条刷新
2017/04/16 Javascript
JS实现二叉查找树的建立以及一些遍历方法实现
2017/04/17 Javascript
Javascript继承机制详解
2017/05/30 Javascript
详解vue中computed 和 watch的异同
2017/06/30 Javascript
关于Vue的路由权限管理的示例代码
2018/03/06 Javascript
JavaScript 斐波那契数列 倒序输出 输出100以内的质数代码实例
2019/09/11 Javascript
javascript设计模式 ? 解释器模式原理与用法实例分析
2020/04/17 Javascript
解决VUE mounted 钩子函数执行时 img 未加载导致页面布局的问题
2020/07/27 Javascript
[34:44]Liquid vs TNC Supermajor 胜者组 BO3 第二场 6.4
2018/06/05 DOTA
[48:11]完美世界DOTA2联赛 Magma vs GXR 第二场 11.07
2020/11/10 DOTA
python进阶教程之循环对象
2014/08/30 Python
Python中的匿名函数使用简介
2015/04/27 Python
Python实现调用另一个路径下py文件中的函数方法总结
2018/06/07 Python
使用 Python 玩转 GitHub 的贡献板(推荐)
2019/04/04 Python
Pandas分组与排序的实现
2019/07/23 Python
Python中Unittest框架的具体使用
2019/08/27 Python
MxNet预训练模型到Pytorch模型的转换方式
2020/05/25 Python
Python 常用日期处理 -- calendar 与 dateutil 模块的使用
2020/09/02 Python
CSS3让登陆面板3D旋转起来
2016/05/03 HTML / CSS
低碳环保标语
2014/06/12 职场文书
监察局领导班子四风问题整改措施思想汇报
2014/10/05 职场文书
vue实现简易音乐播放器
2022/08/14 Vue.js