PHP多进程(二)之pcntl_wait

news2024/11/20 9:11:00

上篇文章我们说到父进程应该回收子进程结束之后产生的数据,这样才会不浪费系统资源。

一个程序启动之后,变成了一个进程,进程在以下情况会退出
1)运行到最后一行语句
2) 运行时遇到return 时
3) 运行时遇到exit()函数的时候
4) 程序异常的时候
5) 进程接收到中断信号

这篇我们认识一个新的函数

pcntl_wait 进程的退出

PHP: pcntl_wait - Manual

pcntl_wait — 等待或返回 fork 的子进程状态

wait函数挂起当前进程的执行直到一个子进程退出或接收到一个信号要求中断当前进程或调用一个信号处理函数如果一个子进程在调用此函数时已经退出( 俗称僵尸进程 ),此函数立刻返回。子进程使用的所有系统资源将被释放。

意思就是说pcntl_wait默认是阻塞状态等待子进程结束,如果子进程没有通过wait回收的话就会变成一个僵尸进程占用资源

僵尸进程

演示僵尸进程前,先来能识别什么是僵尸进程

# linux命令行

ps -aux  


# 筛选php的进程

ps -aux | grep php  



# 进程状态  对应下图红线处

D 不可中断 Uninterruptible(usually IO)

R 运行状态,正在运行

S 处于休眠状态,是可被系统唤醒

T 停止状态

Z 僵尸进程

W 进入内存交换(从内核2.6开始无效)

X 死掉的进程

演示僵尸进程:

$pid = pcntl_fork(); // 开启子进程

if ($pid == 0){
    // 子进程运行结束 并没有被父进程回收的进程 就是僵尸进程
    echo "我是子进程,我的标识是:".posix_getpid().",好了我的任务结束了,拜拜"."\n";
}else{
    echo "我是父进程,我的标识是:".posix_getpid()."\n";
    // 父进程有任务还在运行的时候子进程已经结束了 这个时候子进程的垃圾并未被回收 还在占用这系统资源
    while (1){
        ;
    }
}

# 三种查看方式

pstree -ap | grep php


ps -ef | grep php


ps -aux | grep php

 

# /proc文件系统提供有关系统中进程的信息

ls /proc/

# 查看进程资源

ls /proc/{pid} 

 当我ctrl+c终止掉这个程序的时候,僵尸进程也就不存在了

 让我们来使用pcntl_wait()回收

$pid = pcntl_fork(); // 开启子进程

if ($pid == 0){
    echo "我是子进程,我的标识是:".posix_getpid().",(我接到了爸爸的电话,让我回家去),好,出发"."\n";
    echo "我距离我爸是15步"."\n";
    // 子进程运行任务
    $i = 0;
    while ($i<=14){
        echo "爸爸,我正在回家去,我走了".($i+1).'步'."\n";
        $i++;
        sleep(2);
    }

}else{
    echo "我是父进程,我的标识是:".posix_getpid().',过年了,我打电话让我儿子回家了'."\n";

    $exitPid = pcntl_wait($status);   // 阻塞状态就是一直等待子进程并回收
    echo "我儿子回来了,我的儿子是:".$exitPid."\n";
}

当儿子回家的时候我们通过另外一个连接查看儿子回家的状态

 我们这次子进程不用sleep()函数再看一下效果

$pid = pcntl_fork(); // 开启子进程

if ($pid == 0){
    echo "我是子进程,我的标识是:".posix_getpid().",(我接到了爸爸的电话,让我回家去),好,出发"."\n";
    // 子进程运行任务
    while (1){
        ;
    }

}else{
    echo "我是父进程,我的标识是:".posix_getpid().',过年了,我打电话让我儿子回家了'."\n";

    $exitPid = pcntl_wait($status);   // 阻塞状态就是一直等待子进程并回收
    echo "我儿子回来了,我的儿子是:".$exitPid."\n";
}

我们再来看一下pcntl_wait()参数

pcntl_wait() 将会存储状态信息到 status 参数上,这个通过 status 参数返回的状态信息可以用以下函数 pcntl_wifexited(), pcntl_wifstopped(), pcntl_wifsignaled(), pcntl_wexitstatus(), pcntl_wtermsig() 以及 pcntl_wstopsig() 获取其具体的值。

pcntl_wait() 返回退出的子进程进程号,发生错误时返回 -1,如果提供了 WNOHANG 作为 option(wait3可用的系统)并且没有可用子进程时返回 0。

根据官网的例子说明,接下来我们分别测试:

$pid = pcntl_fork(); // 开启子进程

if ($pid == 0){
    echo "子进程标识是:".posix_getpid()."\n";


    // while (1){
    //     ;
    // }

}else{

    echo "父进程标识是:".posix_getpid()."\n";

    // 不阻塞状态 $exitPid 是返回 0  阻塞状态会等待子进程回收并返回子进程pid
    // 参数二就是不阻塞状态
    $exitPid = pcntl_wait($status,WNOHANG);   // 非阻塞
    // $exitPid = pcntl_wait($status);                // 阻塞

    // $exitPid 有三种状态 成功回收子进程 > 0  失败就是 -1  没有可用子进程返回 0
    // 我们这样就可以增加判断
    if ($exitPid == 0){

        echo "没有可回收进程"."\r\n";

    }elseif($exitPid > 0){

        // 回收子进程成功
        echo "回收子进程成功"."\n";

    }
}

进程退出以及退出状态演示:

// 北风之神yyds
// 1) return exit 函数 正常终止退出
// 2) 中断信号 异常终止退出
// 进程不管是何种方式退出,都会有一部分数据驻留在内存中,比如说终止状态,所以父进程必须使用pcntl_wait函数来回收终止进程所占用的系统资源
// 僵尸进程:就是子进程已经退出,但父进程还没有回收[pcntl_wait] Z
$pid = pcntl_fork(); // 开启子进程

if ($pid == 0){
    echo "子进程标识是:".posix_getpid()."\n";
    // die(5);
    // exit(7);
    // return 1;
    while (1){
        ;
    }

}else{

    echo "父进程标识是:".posix_getpid()."\n";

    // 不阻塞状态 $exitPid 是返回 0  阻塞状态会等待子进程回收并返回子进程pid
    // 参数二就是不阻塞状态
    // $exitPid = pcntl_wait($status,WNOHANG);   // 非阻塞
    $exitPid = pcntl_wait($status);                // 阻塞

    // $exitPid 有三种状态 成功回收子进程 > 0  失败就是 -1  没有可用子进程返回 0
    // 我们这样就可以增加判断
    if ($exitPid == 0){

        echo "没有可回收进程"."\r\n";

    }elseif($exitPid > 0){

        // 回收子进程成功了
        echo "回收子进程成功"."\n";

        // 接下来我们来判断退出状态

        if (pcntl_wifexited($status)){

            // pcntl_wifexited 检查子进程状态代码是否代表正常退出。正常退出时返回 true ,其他情况返回 false。
            // pcntl_wexitstatus  返回一个中断的子进程的返回代码
            echo "子进程是正常退出!"."代码是".pcntl_wexitstatus($status)."\n";

        }elseif (pcntl_wifstopped($status)){

            //  怎么让这里面执行 下面做了补充

            // pcntl_wifstopped  检查子进程当前是否已经停止 进程当前是停止的返回 true ,其他情况返回 false 。
            // pcntl_wstopsig 返回导致子进程停止的信号 返回信号编号。
            echo "子进程停止退出!停止信号是:".pcntl_wstopsig($status)."\n";

        }elseif (pcntl_wifsignaled($status)){

            // pcntl_wifsignaled 检查子进程状态码是否代表由于某个信号而中断 子进程是由于某个未捕获的信号退出的返回 true ,其他情况返回 false 。
            // pcntl_wtermsig  返回导致子进程中断的信号  返回整型的信号编号。
            echo "子进程非正常退出!中断信号是:".pcntl_wtermsig($status)."\n";

        }
    }
}

子进程停止退出补充:

PHP: pcntl_wifstopped - Manual

 $exitPid = pcntl_wait($status,WUNTRACED);      // 阻塞 进程停止会触发 pcntl_wifstopped()函数

 运行测试:

 关于信号可以先看别人的  关于信号后续也会发布文章的。

# 查看所有信号

kill -l

可以参考别的大佬的文章

Linux 信号的详细介绍和举例说明_易点点心动的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/159369.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker搭建maven私服(nexus3),整合springboot上传下载依赖

一、前言 我们在JavaWeb开发中必不可少的就是jar包管理-maven&#xff0c;在没有maven之前&#xff0c;都是自己手动下载jar包导入到项目中&#xff0c;非常的繁琐。 maven出现之后&#xff0c;又迎来新的问题&#xff0c;对于仓库里人家发布的都可以引用下载&#xff0c;但是…

音视频面试基础题

编码原理 为什么巨大的原始视频可以编码成很小的视频呢?这其中的技术是什么呢?核心思想就是去除冗余信息&#xff1a; 1&#xff09;空间冗余&#xff1a;图像相邻像素之间有较强的相关性 2&#xff09;时间冗余&#xff1a;视频序列的相邻图像之间内容相似 3&#xff09…

CVPR21 - BasicVSR:简单有效的视频超分辨率Baseline

文章目录原文信息初识相知组件分析BasicVSRIconVSR部分实验回顾原文信息 原文链接 初识 相比于图像超分&#xff0c;视频超分(VSR&#xff0c;Video Super-Resolution)显然是一件更具挑战性的任务。视频超分比图像超分多了时间维度的信息、更为复杂&#xff0c;而在当时&…

结构体的声明使用及存储方式

文章目录 一、结构体的声明与使用 1、1 结构体的简单声明 1、2 结构体的特殊声明 1、3 结构体自引用 1、4 结构体变量的定义和初始化 1、5 结构体传参 二、结构体在内存中的存储方式 2、1 结构体在内存中的存储方式的引入 2、2 结构体的内存对齐 2、3 修改默认对齐数…

AcWing - 寒假每日一题2023(DAY 1——DAY 5)

文章目录一、AcWing 4261.孤独的照片&#xff08;简单&#xff09;1. 实现思路2. 实现代码二、AcWing 3400.统计次数&#xff08;简单&#xff09;1. 实现思路2. 实现代码三、AcWing 4366. 上课睡觉&#xff08;简单&#xff09;1. 实现思路2. 实现代码四、AcWing 3443. 学分绩…

程序员接私活最最完整攻略

接私活对于程序员这个圈子来说是一个既公开又隐私的话题&#xff0c;当你竭尽全力想要去接私活的时候一定做过这样的事情&#xff0c;百度搜索“程序员如何接私活”、“程序员在哪里接外包”等等问题&#xff0c;今天就送大家最完整攻略&#xff0c;千万别错过了。 做私活挣钱吗…

有趣且重要的Git知识合集(10)git stash操作

这种一般用于多分支&#xff0c;或者多人协同合作时会使用到的git命令 场景1&#xff1a; 当你在dev分支上写了很多代码&#xff0c;此时线上有bug&#xff0c;需要紧急在hotfix分支上修改&#xff0c;那直接git add提交又不太好&#xff0c;毕竟还没有开发完&#xff0c;那么…

JVM 学习笔记 内存结构

内存结构 程序计数器 作用&#xff1a;记录下一条JVM指令的执行地址 特点&#xff1a; 线程私有不存在内存溢出 虚拟机栈 每个线程运行时所需的内存称为虚拟机栈。每个栈由多个栈帧&#xff08;Frame&#xff09;组成&#xff0c;每个栈帧对应每次方法调用时占用的内存。每…

BIOS 的详细介绍

一、BIOS详解 对于不少新手&#xff0c;刷新BIOS还是比较神秘的。而对于一些BIOS相关的知识&#xff0c;不少人也是一知半解。在这里&#xff0c;我们将对BIOS作一次全面的了解。 1、什么是BIOS BIOS是英文"Basic Input Output System"的缩略语&#xff0c;直译…

NTN(三) Timing

微信同步更新欢迎关注同名modem协议笔记。这篇看下k_offset和k_mac&#xff0c;如38.300所述&#xff0c;k_offset是配置的调度偏移量&#xff0c;需要大于或等于service link RTT和Common TA之和&#xff1b;k_mac 是配置的偏移量&#xff0c;需要大于或等于 RP 和 gNB 之间的…

Chem. Eur. J.|针对细胞内靶点的环肽药物:肽药物发展的下一个前沿

​题目&#xff1a;Cyclic Peptides as Drugs for Intracellular Targets: The Next Frontier in Peptide Therapeutic Development 文献来源&#xff1a;Chem. Eur. J. 2021, 27, 1487 – 1513 代码&#xff1a;无&#xff08;环肽综述&#xff09; 内容&#xff1a; 1.简…

5-迷宫问题(华为机试)

题目 定义一个二维数组 N*M&#xff0c;如 5 5 数组如下所示&#xff1a; int maze[5][5] { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫&#xff0c;其中的1表示墙壁&#xff0c;0表示可以走的路&#xff0c;只…

通用模型切片处理过程 CesiumLab系列教程

我们前面把每种格式的模型参数设置已经讲解清楚&#xff0c;下面我们应该弄清楚通用模型切片剩下的流程&#xff0c;不管是人工模型&#xff0c;还是shp矢量面、bim模型&#xff0c;剩下的处理过程都是一样的&#xff0c;这里我们一起讲述。 资源库 ​通用模型处理分为两个过程…

基于JAVA的个人信息管理系统源码,含基于VUE的PC前端及移动端,用于管理个人消费、锻炼、音乐、阅读、健康、饮食等衣食住行信息

项目介绍 完整代码下载地址&#xff1a;基于JAVA的个人信息管理系统源码 用于管理个人消费、锻炼、音乐、阅读、健康、饮食、人生经历等各个衣食住行信息的系统&#xff0c;通过提醒、计划模块利用调度系统来统计分析执行情况。 并通过积分和评分体系来综合评估个人的总体状态…

【C++】类和对象【中篇】--C++六个默认成员函数以及const成员函数

文章目录一、类的6个默认成员函数二、构造函数1.概念2.特性2.1特征分析——自动生成2.2.特征分析——选择处理2.3特征分析——默认构造3.C11补丁——缺省值三、析构函数1.概念2.特征四、拷贝构造函数1.概念2.特征2.1引用分析——引用做参数2.2特征分析——深浅拷贝五、运算符重…

Clin Nutr | 浙大儿童医院-陈洁/倪艳揭示全肠内营养对儿童克罗恩病肠道菌群和胆汁酸代谢的影响...

全肠内营养对儿童克罗恩病肠道微生物群和胆汁酸代谢的影响The impact of exclusive enteral nutrition on the gut microbiome and bile acid metabolism in pediatric Crohns diseaseResearch article&#xff0c;2022年11月30日&#xff0c;Clinical Nutrition&#xff0c;7.…

Weblogic 任意文件上传漏洞(CVE-2018-2894)复现

目录 weblogic 漏洞环境准备 漏洞复现 修复建议 weblogic WebLogic是美国Oracle公司出品的一个application server&#xff0c;确切的说是一个基于JAVAEE架构的中间件&#xff0c;WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应…

Healthcare靶机总结

Healthcare靶机渗透总结 靶机下载地址: https://download.vulnhub.com/healthcare/Healthcare.ova 打开靶机,使用nmap扫描出靶机的ip和所有开放的端口 可以看到,靶机开放了21端口和80端口 21端口为ftp的端口,一般遇到这种,就可以考虑ftp的匿名登录,我们可以试一下 用户名anony…

【总结】华为、H3C、锐捷三家交换机配置命令详解

一直以来&#xff0c;对于华为、H3C、锐捷交换机的命令配置&#xff0c;不断的有朋友留言&#xff0c;三家交换机的配置命令容易弄混&#xff0c;经常在实际项目配置中出错&#xff0c;因此&#xff0c;本期我们将来介绍这三家交换机的基础配置命令&#xff0c;大家可以分别来看…

动手学区块链学习笔记(一):加密算法介绍

引言 本文根据实验楼以及自己查询到的一些资料&#xff08;文末给出&#xff09;&#xff0c;模拟了一下区块链从诞生到交易的整个过程&#xff0c;也算是弥补了一下之前区块链的一些缺失知识。 哈希加密原理介绍 什么是比特币&#xff1f; 比特币是一种加密货币&#xff0c…