进程组和用处

news2024/11/17 23:32:30

进程组:一个或多个进程的集合,进程组id是一个正整数。

组长进程:进程组id == 进程id

组长进程可以创建一个进程组,创建该进程组的进程,终止了,只要进程组有一个进程存在,进程组就存在,与组长进程是否终止无关。

进程组生存期:进程组创建到最后一个进程离开(终止或转移到另一个进程组)

一个进程可以为自己子进程设置进程组id

作用

子进程退出时,不管父子进程同不同一个进程组,都会发SIGCHLD信号给父进程

当父子进程同进程组时,父进程应捕捉SIGCHLD信号,对子进程资源进程回收,防止僵尸进程的产生

当父子进程不同进程组时,比如设置子进程成为了一个新的进程组,这时候子进程退出,系统也会正常回收子进程的资源,不会产生僵尸进程的

相关函数

#include <unistd.h>

int setpgid(pid_t pid, pid_t pgid); //pid = 0, pgid = 0,让当前进程成为一个进程组,并且进程组id为当前进程的pid
pid_t getpgid(pid_t pid); //pid = 0,获取当前进程的进程组id

pid_t getpgrp(void); /* POSIX.1 version */
pid_t getpgrp(pid_t pid); /* BSD version */

int setpgrp(void); /* System V version */
int setpgrp(pid_t pid, pid_t pgid); /* BSD version */

demo

  1. 父子进程同一个进程组
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

void do_sigchld(int signo)
{
    pid_t pid;
    int status;
    printf("signo = %d\n", signo);

    while((pid = waitpid(0, &status, WNOHANG)) > 0) // 0:跟调用进程同组的子进程,WNOHANG:不阻塞,立即返回
    {
        if (WIFEXITED(status))
            printf("child %d exit status %d\n", pid, WEXITSTATUS(status));
        else if (WIFSIGNALED(status))
            printf("chid %d exit by signal %d\n", pid, WTERMSIG(status));
    } 
}

int main(int argc, char *argv[])
{
    pid_t pid;
    //阻塞SIGCHLD信号
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGCHLD);
    sigprocmask(SIG_BLOCK, &set, NULL);

    pid = fork();
    if (pid == 0)
    {
        //in child

        //解除阻塞SIGCHLD信号
        sigprocmask(SIG_UNBLOCK, &set, NULL);

        //进程组
        printf("child pid = %d, process group id getpgid(0) = %d\n", getpid(), getpgid(0));
        printf("child pid = %d, process group id getpgid(getpid()) = %d\n", getpid(), getpgid(getpid()));
        printf("child pid = %d, process group id getpgrp() = %d\n", getpid(), getpgrp());

        /*
        setpgid(0, 0); //pid = 0, pgid = 0,让当前进程成为一个进程组,并且进程组id为当前进程的pid
        printf("after setpgid(0, 0) child pid = %d, process group id getpgid(0) = %d\n", getpid(), getpgid(0));
        printf("after setpgid(0, 0) child pid = %d, process group id getpgid(getpid()) = %d\n", getpid(), getpgid(getpid()));
        printf("after setpgid(0, 0) child pid = %d, process group id getpgrp() = %d\n", getpid(), getpgrp());
        */
    }
    else if (pid > 0)
    {
        //in parent

        //先捕捉SIGCHLD信号
        struct sigaction act;
        act.sa_handler = do_sigchld;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0; //0:用sa_handler参数,SA_SIGINFO:用sa_sigaction参数
        sigaction(SIGCHLD, &act, NULL);

        //再解除阻塞SIGCHLD信号
        sigprocmask(SIG_UNBLOCK, &set, NULL);

        //进程组
        printf("parent pid = %d, process group id getpgid(0) = %d\n", getpid(), getpgid(0));
        printf("parent pid = %d, process group id getpgid(getpid()) = %d\n", getpid(), getpgid(getpid()));
        printf("parent pid = %d, process group id getpgrp() = %d\n", getpid(), getpgrp());

        sleep(1); //为了观察子进程退出时,父进程回收子进程资源
    }
    else
    {
        perror("fork");
        exit(1);
    }

    return 0;
}

  1. 子进程成为一个进程组时,上面的代码加入如下代码后
setpgid(0, 0); //pid = 0, pgid = 0,让当前进程成为一个进程组,并且进程组id为当前进程的pid
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

void do_sigchld(int signo)
{
    pid_t pid;
    int status;
    printf("signo = %d\n", signo);

    while((pid = waitpid(0, &status, WNOHANG)) > 0) // 0:跟调用进程同组的子进程,WNOHANG:不阻塞,立即返回
    {
        if (WIFEXITED(status))
            printf("child %d exit status %d\n", pid, WEXITSTATUS(status));
        else if (WIFSIGNALED(status))
            printf("chid %d exit by signal %d\n", pid, WTERMSIG(status));
    } 
}

int main(int argc, char *argv[])
{
    pid_t pid;
    //阻塞SIGCHLD信号
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGCHLD);
    sigprocmask(SIG_BLOCK, &set, NULL);

    pid = fork();
    if (pid == 0)
    {
        //in child

        //解除阻塞SIGCHLD信号
        sigprocmask(SIG_UNBLOCK, &set, NULL);

        //进程组
        printf("child pid = %d, process group id getpgid(0) = %d\n", getpid(), getpgid(0));
        printf("child pid = %d, process group id getpgid(getpid()) = %d\n", getpid(), getpgid(getpid()));
        printf("child pid = %d, process group id getpgrp() = %d\n", getpid(), getpgrp());

        setpgid(0, 0); //pid = 0, pgid = 0,让当前进程成为一个进程组,并且进程组id为当前进程的pid
        printf("after setpgid(0, 0) child pid = %d, process group id getpgid(0) = %d\n", getpid(), getpgid(0));
        printf("after setpgid(0, 0) child pid = %d, process group id getpgid(getpid()) = %d\n", getpid(), getpgid(getpid()));
        printf("after setpgid(0, 0) child pid = %d, process group id getpgrp() = %d\n", getpid(), getpgrp());
    }
    else if (pid > 0)
    {
        //in parent

        //先捕捉SIGCHLD信号
        struct sigaction act;
        act.sa_handler = do_sigchld;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0; //0:用sa_handler参数,SA_SIGINFO:用sa_sigaction参数
        sigaction(SIGCHLD, &act, NULL);

        //再解除阻塞SIGCHLD信号
        sigprocmask(SIG_UNBLOCK, &set, NULL);

        //进程组
        printf("parent pid = %d, process group id getpgid(0) = %d\n", getpid(), getpgid(0));
        printf("parent pid = %d, process group id getpgid(getpid()) = %d\n", getpid(), getpgid(getpid()));
        printf("parent pid = %d, process group id getpgrp() = %d\n", getpid(), getpgrp());

        sleep(1); //为了观察子进程退出时,父进程回收子进程资源
    }
    else
    {
        perror("fork");
        exit(1);
    }

    return 0;
}

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

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

相关文章

卷积神经网络(CNN)

目录The Basic Usage of CNNPadding&#xff08;填充&#xff09;Weights&#xff08;权重&#xff09;PoolingThe Basic Usage of CNN What are Convolutional Neural Networks? They’re basically just neural networks that use Convolutional layers&#xff08;卷积层…

家政服务小程序实战教程13-接入客服

小程序在微信里使用&#xff0c;以其无需安装随用随走为特点。但是有个问题是&#xff0c;如果提供商品或者服务的&#xff0c;用户如果有问题往往希望平台的运营方给出专业的解答。为了满足这类需求&#xff0c;就需要我们提供客服接入的功能&#xff0c;用户可以点击客服图标…

Linux使用定时任务监控java进程并拉起

需求描述&#xff1a; 设计一个脚本&#xff0c;通过Linux定时任务&#xff0c;每分钟执行一次&#xff0c;监控jar包进程是否存在&#xff0c;存在则不做动作&#xff0c;不存在则重新拉起jar包程序。 定时任务配置&#xff1a; */1 * * * * bash -x /root/myfile/jars/che…

stk 根据六根数文件生成卫星轨迹(一)

先简单介绍下上面的参数。 Propagator预报轨道模型。 TwoBody为二体&#xff08;开普勒运动模型&#xff09;。HPOP为高精度轨道模型。目前只用到这两个。 下图为六根数参数 Orbit Epoch&#xff1a;为根数时间&#xff08;UTC&#xff09; Semimajor Axis&#xff1a;长半…

软考高项——第五章进度管理

范围管理进度管理总线索规划进度管理定义活动活动排序估算活动资源估算活动时间制定进度管理计划控制进度进度管理总线索 进度管理的总线索包括&#xff1a; 1&#xff09;规划进度管理 2&#xff09;定义活动 3&#xff09;活动排序 4&#xff09;估算活动资源 5&#xff09;…

pandas基本操作

df.head()/tail() 查看头/尾5条数据&#xff1b;df.info 查看表格简明概要&#xff1b;df.dtypes 查看字段数据类型&#xff1b;df.index 查看表格索引&#xff1b;df.columns 查看表格列名&#xff1b;df.values 以array形式返回指定数据的取值&#xff1b;list(dt.groupby(&q…

vue2 使用 cesium 篇

vue2 使用 cesium 篇 今天好好写一篇哈&#xff0c;之前写的半死不活的。首先说明&#xff1a;这篇博文是我边做边写的&#xff0c;小白也是&#xff0c;实现效果会同时发布截图&#xff0c;如果没有实现也会说明&#xff0c;仅仅作为技术积累&#xff0c;选择性分享&#xff0…

远程管理时代,还得是智能化PDU才靠得住!

在如今这个信息技术高速发展的时代&#xff0c;数据中心IDC机房服务器数量与日俱增&#xff0c;提供DNS域名服务、主机托管服务、虚拟主机服务等服务的服务器是IDC最基本的功能之一。服务器需要7*24小时不间断持续工作&#xff0c;但当服务器数量很大&#xff0c;服务器工作、重…

.net6API使用AutoMapper和DTO

AutoMapper&#xff0c;是一个转换工具&#xff0c;说到AutoMapper时&#xff0c;就不得不先说DTO&#xff0c;它叫做数据传输对象(Data Transfer Object)。 通俗的来说&#xff0c;DTO就是前端界面需要用的数据结构和类型&#xff0c;而我们经常使用的数据实体&#xff0c;是数…

华为ensp模拟校园网/企业网实例(同城灾备及异地备份中心保证网络安全)

文章简介&#xff1a;本文用华为ensp对企业网络进行了规划和模拟&#xff0c;也同样适用于校园、医院等场景。如有需要可联系作者&#xff0c;可以根据定制化需求做修改。作者简介&#xff1a;网络工程师&#xff0c;希望能认识更多的小伙伴一起交流&#xff0c;私信必回。一、…

多元回归分析 | CNN-LSTM卷积长短期记忆神经网络多输入单输出预测(Matlab完整程序)

多元回归分析 | CNN-LSTM卷积长短期记忆神经网络多输入单输出预测(Matlab完整程序) 目录 多元回归分析 | CNN-LSTM卷积长短期记忆神经网络多输入单输出预测(Matlab完整程序)预测结果评价指标基本介绍程序设计参考资料预测结果 评价指标 训练集平均绝对误差MAE:0.69559 训练…

宝塔搭建实战php源码人才求职管理系统后台端thinkphp源码(一)

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 在开源社区里看到了这一套系统&#xff0c;骑士人才系统SE版&#xff0c;搭建测试了&#xff0c;感觉很不错。能够帮助一些想做招聘平台的朋友降低开发成本&#xff0c;就是要注意&#xff0c;想商业使用的话&…

QT+OpenGL光照2

QTOpenGL材质 本篇完整工程见gitee:QtOpenGL 对应点的tag&#xff0c;由turbolove提供技术支持&#xff0c;您可以关注博主或者私信博主 材质 在现实世界中&#xff0c;每个物体会对光照产生不同的反应 在OpenGL中模拟多种类型的物体&#xff0c;必须为每种物体分别定义一个…

IO模型--从BIO、NIO、AIO到内核select、poll、epoll剖析

IO基本概述 IO的分类 IO以不同的维度划分&#xff0c;可以被分为多种类型&#xff1b;从工作层面划分成磁盘IO&#xff08;本地IO&#xff09;和网络IO&#xff1b; 也从工作模式上划分&#xff1a;BIO、NIO、AIO&#xff1b;从工作性质上分为阻塞式IO与非阻塞式IO&#xff1b…

低代码/零代码的快速开发框架

目前国内主流的低代码开发平台有&#xff1a;宜搭、简道云、明道云、云程、氚云、伙伴云、道一云、JEPaaS、华炎魔方、搭搭云、JeecgBoot 、RuoYi等。这些平台各有优劣势&#xff0c;定位也不同&#xff0c;用户可以根据自己需求选择。 一、阿里云宜搭 宜搭是阿里巴巴集团在20…

分布式文件存储Minio学习入门

文章目录一、分布式文件系统应用场景1. Minio介绍Minio优点2. MinIO的基础概念、3. 纠删码ES(Erasure Code)4. 存储形式5. 存储方案二、Docker部署单机Minio三、minio纠删码模式部署四、分布式集群部署分布式存储可靠性常用方法冗余校验分布式Minio优势运行分布式minio使用dock…

如何设置股票接口版交易软件的指标涨跌家数?

如何设置股票接口版交易软件指标涨跌家数&#xff1f;今天小编就以通达信为例给大家介绍一下&#xff0c;很多人其实不知道通达信里面有个很厉害的股票情绪的指标&#xff0c;叫做通达信涨跌家数&#xff0c;打开在通达信软件k线界面&#xff0c;然后输入880005就可以找到了。下…

如何解决 Python 中 TypeError: unhashable type: ‘dict‘ 错误

Python “TypeError: unhashable type: ‘dict’ ” 发生在我们将字典用作另一个字典中的键或用作集合中的元素时。 要解决该错误&#xff0c;需要改用 frozenset&#xff0c;或者在将字典用作键之前将其转换为 JSON 字符串。 当我们将字典用作另一个字典中的键时&#xff0c…

AnlogicFPGA-IO引脚约束设置

&#xff08;https://www.eefocus.com/article/472120.html此链接是一篇关于XillinxFPGA的IO的状态分析&#xff0c;希望自己也要能了解到AnLogic的IO状态并有对此问题的分析能力&#xff09; 1、DriveStrength: 驱动强度&#xff0c;即最大能驱动的电流大小&#xff08;见带负…

Project Caliper:目标是打造最佳VR手柄

一提到Valve Index&#xff0c;人们很快联想到它的五指追踪VR手柄&#xff0c;这款支持手势追踪和体感反馈的高端VR手柄&#xff0c;是市面上最强大的C端VR手柄之一。尽管如此&#xff0c;它依然存在许多缺陷&#xff0c;比如配备的小型摇杆质量不佳、集成式设计不利于维修、人…