linux php 进程进阶(六)进程组

本文介绍了Linux中的进程组概念,强调其作为一组进程集合的作用,便于信号管理。文章通过示例代码展示了如何创建和管理进程组,包括bash启动时如何成为会话首进程和组长进程,以及PHP中如何使用posix_setpgid设置进程组。通过实例解释了进程组ID和会话ID的区别,并演示了进程 fork 和信号传递的过程。
摘要由CSDN通过智能技术生成

linux php 进程进阶(六)进程组

进程组

进程组,就是一个或是多个进程的集合,每个进程都有一个标识组ID,表示该进程属于哪个进程组。

一般情况下,一个进程组是由一个进程 fork 出来的,之后,它的子进程再去 fork ,最后,得到了一个进程组。当然,单个的进程也是一个进程组。进程组有进程组 id ,它通常是第一个进程的 pid ,也就是组长进程的 pid (以识别进程组)。

创建进程组的目的是用于简化向组内所有进程发送信号的操作,即如果一个信号是发给一个进程组,则这个组内的所有进程都会受到该信号【方便管理】。

进程组的领导进程的PID成为进程组ID。领导进程可以先终结。此时进程组依然存在,并持有相同的PGID,直到进程组中最后一个进程终结。

bash进程启动之后,它会自己调用setsid系统函数把自己设置为会话首进程,也会设置自己为组长进程

// 获取当前进程pid
$pid = posix_getpid();
// 打印当前进程pid,父进程pid,进程组pgid,会话sid
fprintf(STDOUT,"pid=%d,ppid=%d,pgid=%d,sid=%d\n",$pid,posix_getppid(),posix_getpgid($pid),posix_getsid($pid));

执行上述代码后可以发现由于 /bin/bash 进程启动时会调用setsid函数把自己设置为会话首进程,也会设置自己为组长进程,所有看到执行demo1.php 进程的父进程是29228 因为demo1.php在bash进程下执行,会话进程也是29228,使用echo $$ 打印当前 bash 进程pid 为 29228.

为什么pgid 不等于29228 呢?
上面我们说过/bin/bash 启动后会调用 setsid 函数设置自己为会话首进程和组长进程,但是自己脚本显示的组长进程却不是/bin/bash 的pid,这是因为脚本执行会调用 setpgid 函数把当前进程设置为组进程,所以显示的pgid不是29228 而是 2893
在这里插入图片描述

php 设置进程组

<?php

function show(){
    $pid = posix_getpid();
    fprintf(STDOUT,"pid=%d,ppid=%d,pgid=%d,sid=%d\n",$pid,posix_getppid(),posix_getpgid($pid),posix_getsid($pid));
}
show();
$map_pid = [];
$pid = pcntl_fork();
if($pid > 0){
   $map_pid[$pid] = $pid;
   $pid =  pcntl_fork();
   if($pid >0){
        $map_pid[$pid] = $pid;

   }else{
        $ppid = posix_getpid();
        posix_setpgid($pid,$pid);
        $ppid = pcntl_fork();
        if($ppid > 0){
             // 子进程退出回收资源,防止孤儿进程
         	pcntl_waitpid(-1, $status);
          }
    }
}

show();

if($pid > 0){
    while(1){
        // 子进程退出回收资源,防止孤儿进程
       $pid =  pcntl_waitpid(-1, $status);

        if($pid > 0){
            print("pid= $pid 已经结束\n");
            unset($map_pid[$pid]);
		}
        // 子进程退出完后,父进程退出
        if(empty($map_pid)){
           break;
        }

    }
}

posix_setpgid 函数,设置进程为组长进程,需要传入两个参数,第一个是进程pid,第二个是要设置为组长进程的pid

在这里插入图片描述
执行demo2.php 后我们可以看到生成了4个进程,19502进程设置自己为组长进程后fork子进程,子进程pid为19503 ,组id为19502 也就是父进程id

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值