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

所属分类: 网络编程 / PHP编程 阅读数: 1984
收藏 0 赞 0 分享

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

使用pcntl_fork函数可以让PHP实现多进程并发或者异步处理的效果:https://www.jb51.net/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()让这些僵尸进程释放资源,这样,子进程才真正的被终止了,僵尸进程被消除了。

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

更多精彩内容其他人还在看

TP5(thinkPHP5)框架基于ajax与后台数据交互操作简单示例

这篇文章主要介绍了TP5(thinkPHP5)框架基于ajax与后台数据交互操作,结合实例形式分析了thinkPHP5前端基于jQuery的ajax数据提交及后台数据接收、处理相关操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

PHP利用Mysql锁解决高并发的方法

这篇文章主要介绍了PHP利用Mysql锁解决高并发的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

php 后端实现JWT认证方法示例

这篇文章主要介绍了php 后端实现JWT认证方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

ThinkPHP框架实现定时执行任务的两种方法分析

这篇文章主要介绍了ThinkPHP框架实现定时执行任务的两种方法,结合实例形式分析了2种被动执行定时任务的相关操作技巧与注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

PHP命名空间与自动加载类详解

这篇文章主要介绍了PHP命名空间与自动加载类,结合实例形式详细分析了php自动加载类与命名空间原理、使用方法及相关操作注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

PHP时间处理类操作示例

这篇文章主要介绍了PHP时间处理类,结合实例形式分析了DateTime、DateTimeZone、DateInterval及DatePeriod等常用日期时间处理类简单操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

利用PHP扩展Xhprof分析项目性能实践教程

XHProf是Facebook开发的性能调试工具,能帮助直观的统计显示PHP程序执行中各方法函数调用次数和消耗时间,以方便我们排查性能瓶颈并进行调优。下面这篇文章主要给大家介绍了关于利用PHP扩展Xhprof分析项目性能实践的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Django 标签筛选的实现代码(一对多、多对多)

这篇文章主要介绍了Django 标签筛选的实现代码(一对多、多对多),本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

PHP使用pdo实现事务处理操作示例

这篇文章主要介绍了PHP使用pdo实现事务处理操作,结合实例形式较为详细的分析了php基于pdo实现事务处理的相关原理与操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

thinkPHP框架实现类似java过滤器的简单方法示例

这篇文章主要介绍了thinkPHP框架实现类似java过滤器的简单方法,结合实例形式分析了thinkPHP基于继承实现的登录验证功能相关操作方法,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多