僵尸进程

当子进程运行结束,父进程仍然继续运行,但父进程没有对子进程进行回收,释放子进程占用的资源,此时子进程就成为了一个僵尸进程。

在Unix进程管理中,如果新开的子进程运行结束,父进程将会收到一个SIGCHLD信号,子进程暂时成为僵尸进程,等待父进程进行处理。如果父进程一直不处理,该进程将会一直存在,占用系统进程表项,永久成为僵尸进程。如果僵尸进程过多,导致系统没有可用的进程表项,将无法运行其他的应用程序。

<?php
$str = "hello world!" . PHP_EOL;
$pid = pcntl_fork();
if ($pid > 0) {
echo "我是主进程,id是" . getmypid() . ",子进程的pid是{$pid}" . PHP_EOL;
pcntl_async_signals(true);
pcntl_signal(SIGCHLD, function () {
echo '子进程退出了,请及时处理' . PHP_EOL;
});
while (1) { //模拟主进程一直运行
sleep(1);
}
} elseif($pid==0) {
echo "我是子进程,我的pid是". getmypid() ."\n";
}else{
echo "我是主进程,开启子进程失败\n";
}

使用ps查看僵尸进程:

ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'

终端会输出:

Z+     7136   7137 [php] <defunct>

当主进程退出之后,子进程将会被init接管并处理

使用 pcntl_wait 回收僵尸进程:

<?php
echo time() . PHP_EOL;
$pid = pcntl_fork();
if ($pid > 0) { //主进程代码
pcntl_wait($status); //父进程阻塞方式等待子进程的退出
echo time() . PHP_EOL;
} elseif($pid==0) {
sleep(3);
echo "我是子进程,我的pid是". getmypid() ."\n";
exit();
}else{
die("我是主进程,开启子进程失败\n");
}
1589874657
我是子进程,我的pid是16140
1589874660

pcntl_wait($status); 默认为阻塞方式回收子进程,可以设置第二个参数为 WNOHANG 即为非阻塞方式回收子进程,代码会继续往下执行,子进程退出后会自动回收。

多个子进程只需要一个pcntl_wait即可回收完成。

在父进程中,为SIGCHLD配置handler来回收:

<?php
pcntl_async_signals(true); pcntl_signal(SIGCHLD, function () {
echo "SIGCHLD" . PHP_EOL;
pcntl_wait($status); //父进程阻塞方式等待子进程的退出
}); echo time() . PHP_EOL;
$pid = pcntl_fork();
if ($pid > 0) { //主进程代码
sleep(10);
echo time() . PHP_EOL;
} elseif($pid==0) {
sleep(3);
echo "我是子进程,我的pid是". getmypid() ."\n";
exit;
}else{
die("我是主进程,开启子进程失败\n");
}
1589874039
我是子进程,我的pid是12875
SIGCHLD
1589874040

忽略子进程结束信号,由init回收:

<?php
pcntl_async_signals(true);
pcntl_signal(SIGCHLD, SIG_IGN); echo time() . PHP_EOL;
$pid = pcntl_fork();
if ($pid > 0) { //主进程代码
sleep(10);
echo time() . PHP_EOL;
} elseif($pid==0) {
sleep(3);
echo "我是子进程,我的pid是". getmypid() ."\n";
exit;
} else {
die("我是主进程,开启子进程失败\n");
}
1589874331
1589874331
我是子进程,我的pid是14493

孤儿进程

孤儿进程是指在其父进程执行完成或被终止后仍继续运行的一类进程。这些孤儿进程将被init进程收养,并由init进程对它们完成回收工作。

孤儿进程没有任何危害,只需要注意自己的代码逻辑即可。

<?php
$pid = pcntl_fork();
if ($pid == -1) {
die('fork error');
} elseif ($pid > 0) {
echo "爸爸先走了,儿子你好好干活" . PHP_EOL;
exit(); // 主进程在很短的时间内已经退出
} else {
// 子进程继续运行
$i = 10;
while($i) {
echo $i;
$i--;
sleep(1);
}
}
爸爸先走了,儿子你好好干活
1111111111...

孤儿进程与僵尸进程的区别

僵尸进程:一个子进程在其父进程还没有调用wait()或waitpid()的情况下退出,这个子进程就是僵尸进程。任何一个子进程在退出之后,并非马上就消失掉,而是留下一个称为僵尸进程的数据结构,等待父进程处理。这是每个子进程在结束时都要经过的阶段。如果子进程在退出之后,父进程没有来得及处理,那么子进程就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程。此为僵尸进程的危害,应当避免。

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程收养,并由init进程对它们完成回收工作。每当一个孤儿进程出现,内核就把孤 儿进程的父进程设置为init,而init进程会循环地wait()已经退出的子进程。这样,当一个孤儿进程结束其生命周期的时候,init进程就会进行回收工作。因此孤儿进程并不会有什么危害 。

PHP 中的僵尸进程、孤儿进程详解的更多相关文章

  1. 进程,多进程,进程与程序的区别,程序运行的三种状态,multiprocessing模块中的Process功能,和join函数,和其他属性,僵尸与孤儿进程

    1.进程 什么是进程: 一个正在被运行的程序就称之为进程,是程序具体执行的过程,是一种抽象概念,进程来自操作系统 2.多进程  多个正在运行的程序 在python中实现多线程的方法 from mult ...

  2. day34 并行并发、进程开启、僵尸及孤儿进程

    day34 并行并发.进程开启.僵尸及孤儿进程 1.并行与并发 什么是并行? 并行指的是多个进程同时被执行,是真正意义上的同时 什么是并发? 并发指的是多个程序看上去被同时执行,这是因为cpu在多个程 ...

  3. 僵尸进程 & 孤儿进程

    参考博文 基本概念 僵尸进程:是所有进程都会进入的一种进程状态,子进程退出,而父进程并没有调用 wait() 或 waitpid() 获取子进程的状态信息,那么子进程的 PID 和 进程描述符 等资源 ...

  4. Go Exec 僵尸与孤儿进程

    原文地址:Go Exec 僵尸与孤儿进程 最近,使用 golang 去管理本地应用的生命周期,期间有几个有趣的点,今天就一起看下. 场景一 我们来看看下面两个脚本会产生什么问题: 创建两个 shell ...

  5. Python并发编程03 /僵孤进程,孤儿进程、进程互斥锁,进程队列、进程之间的通信

    Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 目录 Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 1. 僵尸进程/孤儿进 ...

  6. 「微信小程序」PHP异步进程async-helper实例详解

    PHP异步进程async-helper实例详解 PHP 的异步进程助手,借助于 AMQP 实现异步执行 PHP 的方法,将一些很耗时.追求高可用.需要重试机制的操作放到异步进程中去执行,将你的 HTT ...

  7. Java中堆内存和栈内存详解2

    Java中堆内存和栈内存详解   Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...

  8. 教程-Delphi中Spcomm使用属性及用法详解

    Delphi中Spcomm使用属性及用法详解 Delphi是一种具有 功能强大.简便易用和代码执行速度快等优点的可视化快速应用开发工具,它在构架企业信息系统方面发挥着越来越重要的作用,许多程序员愿意选 ...

  9. Linux中redis安装配置及使用详解

    Linux中redis安装配置及使用详解 一. Redis基本知识 1.Redis 的数据类型 字符串 , 列表 (lists) , 集合 (sets) , 有序集合 (sorts sets) , 哈 ...

  10. Android 中各种权限深入体验及详解

    Android 中各种权限深入体验及详解 分类: Android2012-07-15 19:27 2822人阅读 评论(0) 收藏 举报 androidpermissionsinstallersyst ...

随机推荐

  1. Mysql百万级数据索引重新排序

    参考https://blog.csdn.net/pengshuai007/article/details/86021689中思路解决自增id重排 方式一 alter table `table_name ...

  2. Alamofire-5.0.0 以上报错

    摘要 Alamofire 更新到新版本时,遇到了两个错误和一个警告️,所以记录下来它们,以及如何解决它们.给其他出现类似问题的同道一些解决的方向. 今天新开启一个项目,因为网络请求选择 Alamofi ...

  3. 剖析虚幻渲染体系(13)- RHI补充篇:现代图形API之奥义与指南

    目录 13.1 本篇概述 13.1.1 本篇内容 13.1.2 概念总览 13.1.3 现代图形API特点 13.2 设备上下文 13.2.1 启动流程 13.2.2 Device 13.2.3 Sw ...

  4. ubuntu 10.04安装和配置Samba

    1. 安装samba服务器 sudo apt-get install samba  //主程序包 sudo apt-get install smbfs  //文件下载挂载工具 2. 创建共享目录 mk ...

  5. 用 Go 实现一个 LRU cache

    前言 早在几年前写过关于 LRU cache 的文章: https://crossoverjie.top/2018/04/07/algorithm/LRU-cache/ 当时是用 Java 实现的,最 ...

  6. LuoguB2035 判断数正负 题解

    Content 给定一个数 \(n\),判断这个数的正负. 数据范围:\(-10^9\leqslant n\leqslant 10^9\). Solution 一个基础的分支结构题. if-else ...

  7. LuoguP5006 [yLOI2018] 大美江湖 题解

    Content 题意实在是太过复杂了,因此请回到题面查看. Data Range 本部分和 Solution 部分变量的含义同题面. \(1\leqslant n,m\leqslant 100,0\l ...

  8. Shell 丢弃错误和输出信息

    shell中使用>/dev/null 2>&1 丢弃信息   在一些Shell脚本中,特别是Crontab的脚本中,经常会看到 >/dev/null 2>&1这 ...

  9. FlashFXP链接到服务器上,如果www目录下的文件隐藏

    FlashFXP链接到服务器上,如果www目录下的文件隐藏,那么请按照如下设置,就可以显示隐藏的文件了 [站点]->[站点管理器]->选项,然后按照如下设置:

  10. 分布式系统一致性算法(Paxos)

    CAP理论    一致性(Consistency)    可用性(Availability)    分区容错性(网络分区)Partition toleranceCAP理论的特点,就是CAP只能满足其中 ...