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 相关文章推荐
超级简单的发送邮件程序
Oct 09 PHP
使用PHP socke 向指定页面提交数据
Jul 23 PHP
优化PHP程序的方法小结
Feb 23 PHP
深入理解require与require_once与include以及include_once的区别
Jun 05 PHP
解析PHP的session过期设置
Jun 29 PHP
php生成随机数的三种方法
Sep 10 PHP
浅谈PHP中output_buffering
Jul 13 PHP
php打包网站并在线压缩为zip
Feb 13 PHP
thinkphp jquery实现图片上传和预览效果
Jul 22 PHP
Laravel中任务调度console使用方法小结
May 07 PHP
为何说PHP引用是个坑,要慎用
Apr 02 PHP
PHP实现微信提现功能(微信商城)
Nov 21 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 文件夹删除、php清除缓存程序
2009/08/25 PHP
PHP 数组遍历方法大全(foreach,list,each)
2010/06/30 PHP
PHP程序开发范例学习之表单 获取文本框的值
2011/08/08 PHP
ThinkPHP验证码和分页实例教程
2014/08/22 PHP
yii2 页面底部加载css和js的技巧
2016/04/21 PHP
CI(CodeIgniter)框架实现图片上传的方法
2017/03/24 PHP
JavaScript Event学习第六章 事件的访问
2010/02/07 Javascript
jQuery的初始化与对象构建之浅析
2011/04/12 Javascript
表单类各种类型(文本框)失去焦点效果jquery代码
2013/04/26 Javascript
JSON 数字排序多字段排序介绍
2013/09/18 Javascript
JavaScript用Number方法实现string转int
2014/05/13 Javascript
jQuery中prop()方法用法实例
2015/01/05 Javascript
js与applet相互调用的方法
2016/06/22 Javascript
JS基于onclick事件实现单个按钮的编辑与保存功能示例
2017/02/13 Javascript
浅谈原型对象的常用开发模式
2017/07/22 Javascript
react native与webview通信的示例代码
2017/09/25 Javascript
详解node child_process模块学习笔记
2018/01/24 Javascript
angular基于ng-alain定义自己的select组件示例
2018/02/23 Javascript
浅谈Vue内置component组件的应用场景
2018/03/27 Javascript
详解Vue CLI3配置解析之css.extract
2018/09/14 Javascript
vue中使用better-scroll实现滑动效果及注意事项
2018/11/15 Javascript
Python中下划线的使用方法
2015/03/27 Python
Python实现的使用telnet登陆聊天室实例
2015/06/17 Python
基于pandas数据样本行列选取的方法
2018/04/20 Python
Python解决两个整数相除只得到整数部分的实例
2018/11/10 Python
使用python实现对元素的长截图功能
2019/11/14 Python
浅谈keras中自定义二分类任务评价指标metrics的方法以及代码
2020/06/11 Python
Python3爬虫关于代理池的维护详解
2020/07/30 Python
CSS3的Flexbox布局的简明入门指南
2016/04/08 HTML / CSS
实例讲解利用HTML5 Canvas API操作图形旋转的方法
2016/03/22 HTML / CSS
美国派对用品及装饰品网上商店:Shindigz
2016/07/30 全球购物
Intersport西班牙:在线体育商店
2019/11/06 全球购物
安全生产目标管理责任书
2014/07/25 职场文书
2014年学校总务处工作总结
2014/12/08 职场文书
如何通过简单的代码描述Angular父组件、子组件传值
2022/04/07 Javascript
MongoDB支持的索引类型
2022/04/11 MongoDB