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之第十天
Oct 09 PHP
PHP中动态显示签名和ip原理
Mar 28 PHP
PHP文件注释标记及规范小结
Apr 01 PHP
php中使用__autoload()自动加载未定义类的实现代码
Feb 06 PHP
php二维数组转成字符串示例
Feb 17 PHP
递归删除一个节点以及该节点下的所有节点示例
Mar 19 PHP
PHP和C#可共用的可逆加密算法详解
Oct 26 PHP
PHP调试的强悍利器之PHPDBG
Feb 22 PHP
Laravel中的chunk组块结果集处理与注意问题
Aug 15 PHP
PHP htmlspecialchars() 函数实例代码及用法大全
Sep 18 PHP
laravel5.1框架model类查询的实现方法
Oct 08 PHP
Laravel 连接(Join)示例
Oct 16 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+mysql来做一个功能强大的在线计算器
2010/10/12 PHP
php判断手机访问还是电脑访问示例分享
2014/01/20 PHP
Yii2中DropDownList简单用法示例
2016/07/18 PHP
PHP中error_reporting函数用法详细介绍
2017/06/11 PHP
使用php自动备份数据库表的实现方法
2017/07/28 PHP
PHP 中魔术常量的实例详解
2017/10/26 PHP
YII2框架使用控制台命令的方法分析
2020/03/18 PHP
JavaScript函数中关于valueOf和toString的理解
2016/06/14 Javascript
浅谈JavaScript对象与继承
2016/07/10 Javascript
nodejs根据ip数组在百度地图中进行定位
2017/03/06 NodeJs
利用Vue.js+Node.js+MongoDB实现一个博客系统(附源码)
2017/04/24 Javascript
JS表单提交验证、input(type=number) 去三角 刷新验证码
2017/06/21 Javascript
AngularJS基于provider实现全局变量的读取和赋值方法
2017/06/28 Javascript
基于javaScript的this指向总结
2017/07/22 Javascript
初探Vue3.0 中的一大亮点Proxy的使用
2018/12/06 Javascript
vue添加class样式实例讲解
2019/02/12 Javascript
Nodejs对postgresql基本操作的封装方法
2019/02/20 NodeJs
浅析Angular 实现一个repeat指令的方法
2019/07/21 Javascript
javascript导出csv文件(excel)的方法示例
2019/08/25 Javascript
javascript实现支付宝滑块验证码效果
2020/07/24 Javascript
python实现汉诺塔递归算法经典案例
2021/03/01 Python
python如何爬取个性签名
2018/06/19 Python
matplotlib实现热成像图colorbar和极坐标图的方法
2018/12/13 Python
Python后台开发Django会话控制的实现
2019/04/15 Python
浅谈Python 递归算法指归
2019/08/22 Python
Python循环实现n的全排列功能
2019/09/16 Python
Pycharm中import torch报错的快速解决方法
2020/03/05 Python
python标准库OS模块详解
2020/03/10 Python
python如何求圆的面积
2020/07/01 Python
python opencv图像处理(素描、怀旧、光照、流年、滤镜 原理及实现)
2020/12/10 Python
适合各种场合的美食礼品:Harry & David
2016/08/03 全球购物
JSF面试题:如何管量web层中的Bean,用什么标签。如何通过jsp页面与Bean绑定在一起进行处理?
2012/10/05 面试题
销售类个人求职信范文
2013/09/25 职场文书
优秀员工年终发言演讲稿
2014/01/01 职场文书
化学专业毕业生求职信
2014/07/28 职场文书
2016新年慰问信范文
2015/03/25 职场文书