【操作系统】进程组Group|进程会话Session

第04章 初始化程序(5):按下 Ctrl+C 的连锁反应 —— 拆解进程组、会话期与控制终端 进程组,顾名思义,就是一个或多个进程的集合。内核给每个进程组分配了一个进程组标识号(PGID,原文称为 gid)。一个进程组的组号(PGID)一定是一个正整数。组长(Group Leader):每个进程组都有一个组长。组长进程的特点非常简单——它的 PID 等于它的 PGID。也就是说,它是这个团队成立的“发起人”。从PID到PGID,再到SID(会话 ID),Linux 内核层层递进地构建了一个极其严密的多任务管理模型。PID赋予了进程独立的人格。PGID将进程组织成了相互配合的“部队”。 阅读详情

🔥博客主页: 我要成为C++领域大神
🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】
❤️感谢大家点赞👍收藏⭐评论✍️

本博客致力于知识分享,与更多的人进行学习交流

亲缘关系

Linux操作系统下,进程间的关系是强亲缘(父子),弱亲缘(爷孙)

爷爷进程与孙子进程最低限度亲缘(继承关系)

强亲缘关系(父子进程),子进程被父进程创建,子进程的任务被父进程指定,继承父进程数据,子进程结束后,父进程负责回收避免僵尸问题,整个子进程的生命周期父进程要全程参与。(“中国式家长”)

在shell下执行的所有命令创建的进程都是shell的子进程。

我们来验证一下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/fcntl.h>
 

int main()
{
    printf("Child Process PID:%d\n",getpid());
    printf("Parent Process PID:%d\n",getppid());
    while(1){
        sleep(1);
    }
	return 0;
}

getppid即get parent pid,获取父进程的pid

在操作系统中,fork创建进程+execl重载进程是广泛使用

Process Group进程组

一个进程组一般由一个组长和若干组员组成。

终端进程被创建,默认就是进程组的组长进程(系统会分配一个进程组)。

组长进程的唯一标志:组id==进程id

getpid(),返回进程pid
getppid(),返回进程父进程的pid
getpgrp(),返回进程进程组的id

使用这三个函数查看一个进程组之间的关系:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/fcntl.h>
 

int main()
{
    int i;
    pid_t pid;
    for(i=0;i<3;++i){
        pid=fork();
        if(pid==0) break;
    }
    if(pid>0){
    printf("Parent PID:%d,PPID:%d,GroupID:%d\n",getpid(),getppid(),getpgrp());
    }
    else if(pid==0){
    printf("Child PID:%d,PPID:%d,GroupID:%d\n",getpid(),getppid(),getpgrp());
    }else{
        perror("fork call failed");
        exit(0);
    }
	return 0;
}

进程组的销毁:组中最后一个进程,结束或转移,进程组中没有进程时系统会释放进程。

就近原则:子进程被创建后默认归纳到父进程同组的组员

组长是不允许转移的。

组长进程无法创建进程组,组员进程可以创建新组,脱离原有进程组,成为新的组长

子进程成立新组后,亲缘关系不变,子进程依然由父进程回收(子进程脱离原有进程组,父进程可以通过waitpid跨组回收)

setpgid(pid_t pid,pid_t gid)

可以让组员创建新组,也可以将一个组员转移到其他组。

转移时目标组必须存在,需要对目标组有访问权限才可以完成转移

创建:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/fcntl.h>
 

int main()
{
    int i;
    pid_t pid;
    for(i=0;i<3;++i){
        pid=fork();
        if(pid==0) break;
    }
    if(pid>0){
    printf("Parent %d PID:%d,PPID:%d,GroupID:%d\n",i,getpid(),getppid(),getpgrp());
    }
    else if(pid==0){
        if(i==2)//对创建的一个子进程脱离当前组创建一个新的组
        { 
    printf("Child %d PID:%d,PPID:%d,GroupID:%d\n",i,getpid(),getppid(),getpgrp());     
    printf("Child %d PID:%d is Creating Group\n",i,getpid());
    setpgid(getpid(),getpid());
    printf("Child %d PID:%d,GroupID:%d\n",i,getpid(),getpgrp());
             
        }
    printf("Child %d PID:%d,PPID:%d,GroupID:%d\n",i,getpid(),getppid(),getpgrp());
    }else{
        perror("fork call failed");
        exit(0);
    }
	return 0;
}

转移:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main() {
    pid_t pid1, pid2;
    pid_t gpid = -1; // 用于存储新进程组的组ID

    // 创建第一个子进程
    if ((pid1 = fork()) < 0) {
        perror("fork error");
        exit(1);
    } else if (pid1 == 0) {
        // 第一个子进程
        printf("Child 1 PID:%d, PPID:%d, GroupID:%d\n", getpid(), getppid(), getpgrp());

        // 创建新的进程组
        if (setpgid(getpid(), getpid()) < 0) {
            perror("setpgid error for Child 1");
            exit(1);
        }

        printf("Child 1 PID:%d is Creating Group with GroupID:%d\n", getpid(), getpgrp());
        printf("Child 1 PID:%d, GroupID:%d\n", getpid(), getpgrp());

        // 子进程1循环等待
        while (1) {
            sleep(1);
        }
    }

    // 父进程
    printf("Parent PID:%d, GroupID:%d\n", getpid(), getpgrp());

    // 延时等待第一个子进程完成创建新进程组
    sleep(1); // 等待1秒,确保第一个子进程已经执行完setpgid

    // 获取第一个子进程的组ID
    gpid = pid1;

    // 创建第二个子进程
    if ((pid2 = fork()) < 0) {
        perror("fork error");
        exit(1);
    } else if (pid2 == 0) {
        // 第二个子进程
        printf("Child 2 PID:%d, PPID:%d, GroupID:%d\n", getpid(), getppid(), getpgrp());

        // 将第一个子进程移动到新的进程组中
        if (setpgid(getpid(), gpid) < 0) {
            perror("setpgid error for Child 2");
            exit(1);
        }

        printf("Child 2 PID:%d is Changing Group for Child 1\n", getpid());
        printf("Child 2 PID:%d, GroupID:%d\n", getpid(), getpgrp());

        // 子进程2循环等待
        while (1) {
            sleep(1);
        }
    }

    // 父进程等待所有子进程结束
    wait(NULL);
    wait(NULL);

    return 0;
}

Process Session会话关系

会话是一种终端进程管理的组织结构。

在一个终端下创建的一组会话。会话发起者杀死进程是按组杀死的。

关闭终端,在这个会话组创建的其他进程也被杀死了。

如果子进程创建新组了可以存活,但是这个子进程并没有脱离会话。

如果子进程脱离了会话,创建新的会话,也可以存活。(脱离控制终端)

如何脱离控制终端会话?

当一个终端关闭时,那么该终端下创建的其它会话参与者也会被杀死。那么有没有方法避免会话参与者被杀死呢?

1、新建组
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/fcntl.h>
 

int main()
{
    int i;
    pid_t pid;
    for(i=0;i<3;++i){
        pid=fork();
        if(pid==0) break;
    }
    if(pid>0){
    printf("Parent %d PID:%d,PPID:%d,GroupID:%d\n",i,getpid(),getppid(),getpgrp());
    while(1) sleep(1);
    }
    else if(pid==0){
    if(i==1)
    { 
    printf("Child %d PID:%d,PPID:%d,GroupID:%d\n",i,getpid(),getppid(),getpgrp());
    printf("Child %d PID:%d is Creating Group\n",i,getpid());
    setpgid(getpid(),getpid());
    printf("Child %d PID:%d GroupId:%d  SessionID:%d\n",i,getpid(),getpgrp(),getsid(getpid()));
    while(1) sleep(1);
    }
    printf("Child %d PID:%d,PPID:%d,GroupID:%d\n",i,getpid(),getppid(),getpgrp());
    }else{
        perror("fork call failed");
        exit(0);
    }
	return 0;
}

创建了新组的子进程仍然存活。

2、新建会话

使用setsid()函数创建新的会话。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/fcntl.h>
 

int main()
{
    int i;
    pid_t pid;
    for(i=0;i<3;++i){
        pid=fork();
        if(pid==0) break;
    }
    if(pid>0){
    printf("Parent %d PID:%d,PPID:%d,GroupID:%d\n",i,getpid(),getppid(),getpgrp());
    while(1) sleep(1);
    }
    else if(pid==0){
    if(i==1)
    { 
    printf("Child %d PID:%d,PPID:%d,GroupID:%d\n",i,getpid(),getppid(),getpgrp());
    printf("Child %d PID:%d is Changing Sessin\n",i,getpid());
    setsid();
    printf("Child %d PID:%d GroupId:%d  SessionID:%d\n",i,getpid(),getpgrp(),getsid(getpid()));
    while(1) sleep(1);
    }
    printf("Child %d PID:%d,PPID:%d,GroupID:%d\n",i,getpid(),getppid(),getpgrp());
    }else{
        perror("fork call failed");
        exit(0);
    }
	return 0;
}

创建了新会话的进程仍然存活。

24年电赛H题 | 想要小车走直线,正在调角度环,但不知道怎么把角度偏航角偏差转化成电机速度输出? 🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。 阅读详情

相关推荐

手把手教你用周立功USBCANFD-200U和ZCANPRO软件,从驱动安装到UDS诊断一条龙搞定

本文详细介绍了如何使用周立功USBCANFD-200U硬件和ZCANPRO软件,从驱动安装到UDS诊断的全流程操作指南。涵盖硬件连接、软件配置、CAN通信测试及UDS诊断实战,帮助汽车电子爱好者和工程师快速掌握CAN总线通信技术,实现专业的车辆诊断功能。

weixin_30752699的博客 578

进程组与会话

进程组与会话 进程组 什么是进程组? 进程组:一组协同工作或关联进程的集合,每个进程组有ID(PGID) 每个进程属于一个进程组,每一个进程组有一个进程组长,该进程组长ID(PID)与进程组ID(PGID)相同 一个信号可以发送给进程组的所有进程、让所有进程终止、暂停或继续运行 会话 什么是会话? 会话是一个或多个进程组的集合 当用户登录系统时,登录进程会为这个用户创建一个新的会话(session) shell进程(如bash)作为会话的第一个进程,称为会话进程(session lea

Scroll_C的博客 694

k8s部署 普罗米修斯(Prometheus)监控

Prometheus是一个开源的服务监控系统和时序数据库其提供了通用的数据模型和快捷数据采集、存储和查询接口它的核心组件Prometheus服务器定期从静态配置的监控目标或者基于服务发现自动配置的目标中进行拉 取数据新拉取到啊的 数据大于配置的内存缓存区时,数据就会持久化到存储设备当中。

D2961953033的博客 3854

进程组和会话

进程组是若干个进程的集合,每个进程组都有一个组长,不管组长终止与否,只要有进程运行 进程组就存在,组长的pid就是getpgrp()。 会话是进程组的集合,包含多个进程组,但是只有一个前台进程组。 进程调用setsid可以建立新对话期,成功调用返回进程组id,出错返回-1,调用函数的进程如果不是组长, 则此函数创建一个新的会话期。 1.此进程称为新的会话的首进程,也是目前唯一一个进程。 ...

BJUT_bluecat的博客 786

Cisco Packet Tracert 无线路由器配置

Cisco Packet Tracert 无线路由器配置

yushan_caoyu的博客 2万+

微型纵向加密在新能源场站中的实战部署与运维避坑指南

本文详细解析了微型纵向加密在新能源场站中的实战部署与运维技巧。通过国密算法SM4实现数据加密,确保新能源场站通信安全,同时提供非侵入式部署方案和运维避坑指南,帮助提升网络稳定性和运维效率。

weixin_30505225的博客 594

Linux 进程关系

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!Linux的进程相互之间有一定的关系。比如说,在Linux进程基础中,我们看到,每个进程都有父进程,而所有的进程以init进程为根,形成一个树状结构。我们在这里讲解进程组和会话,以便以更加丰富的方式了管理进程。进程组 (process group)每个进程都会属于一个进程组(proce

ZhangGeng's Blog 1118

【agent实操】OpenClaw玩转股票分析多个AI智能体(agent)出谋划策

本文介绍了一个基于OpenClaw的多Agent股票分析系统。该系统采用"三人组+总调度"模式,包含三个核心Agent:小牛马(策略中枢)、牛老二(基本面分析师)和牛老三(技术面分析师)。相比单Agent模式,该系统具有分析更专业、权限分级更安全、成本控制更优等优势。文章详细说明了系统部署的6个步骤,包括创建独立Agent工作区、配置专属人设与技能等,并提供了环境检查命令和验证方法。通过这种多Agent协作的方式,可以实现更专业、更安全的股票分析。

海兰 806

第五章_进程 : 进程,进程组,会话关系

进程 进程是操作系统的一个核心概念。每个进程都有自己唯一的标识:进程ID,也有自己的生命周期。一个典型的进程的生命周期如图4-1所示。 进程都有父进程,父进程也有父进程,这就形成了一个以init进程为根的家族树。除此以外,进程还有其他层次关系:进程、进程组和会话。 进程组和会话在进程之间形成了两级的层次:进程组是一组相关进程的集合,会话是一组相关进程组的集合。 这样说来,一个进程会有如下ID: ·PID:进程的唯一标识。对于多线程的进程而言,所有线程调用getpid函数会返回相同的值。 ·PGID:进程组

matafeiyanll的博客 1412

多智能体强化学习MATD3算法完整复现与分析

多智能体强化学习MATD3算法复现与分析摘要 MATD3算法是多智能体深度强化学习领域的重要进展,通过改进MADDPG算法,引入双Q学习、延迟策略更新和目标策略平滑等技术,显著提升了算法稳定性。本文完整复现了MATD3算法,详细解析了其数学原理,包括部分可观测马尔可夫博弈模型和TD3核心思想。在实现层面,设计了集中式Critic和分布式Actor的神经网络架构,采用PyTorch框架构建了Actor-Critic网络模块,包含精心设计的权重初始化和训练流程。该算法有效解决了多智能体环境中的非平稳性、信用分配

max500600的博客 524

⑩电子产品拆解分析-家用无线遥控开关433Mhz

①免布线随意贴,装上就能使用解决单线开关烦恼;②遥控配对简单,无线通讯距离长,信号可穿墙;

a6662580的博客 4681

进程组与会话 Linux Process Groups and Sessions

在类Unix系统中,用户通常会跟各种相关的进程打交道。虽然在登录的时候只有一个终端进程(用户对应的登录shell ,通过这个shell启动各种程序和服务),但通常不久以后就会产生许多相关的进程,例如进行如下动作: 在后台运行无交互的程序(例如bash命令中末位的"&") 通过shell的 job control在各种交互进程之间切换 通过管道启动一组程序 在图形环境下(例如X...

a_18067的博客 239

即插即用系列(代码实践) | CVPR 2025 FDConv:频域动态卷积,打破密集预测任务的参数效率瓶颈

本文提取自 CVPR 2025 的最新底层算子革新论文《Frequency Dynamic Convolution for Dense Image Prediction》。近年来,动态卷积(Dynamic Convolution)通过融合多个并行卷积核极大地提升了模型性能,但研究表明:这些并行卷积核在频域上的响应高度相似,导致了极其严重的参数浪费,且缺乏对不同频率特征的自适应能力。本文复现了该网络的核心架构——FDConv(频率动态卷积)。该方案创造性地在傅里叶域(Fourier Domain)中学习固定参

分享顶会顶刊论文即插即用模块 108

进程组,作业与会话

一、进程组、作业、会话 1.进程组(process group)      每个进程除了有一个进程ID(保存在PCB当中),还属于一个进程组。进程组由一个或多个进程组成,通常和一个作业相关联,可以接收来自同一终端的各种信号。每个进程组有一个唯一的进程组ID。      每个进程组都有一个组长进程,组长进程的ID等于组ID。      组长进程可以组建一个进程组。只要进程组中有一个进程存在,

Sekai_Z的博客 2402

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

为什么需要会话(session)和进程组(process group)?怎样安全的在后台运行程序?

What A process group is a collection of related processes which can all be signalled at once. A session is a collection of process groups, which are either attached to a single terminal device (known as the controlling terminal) or not attached to any term

yiyeshuanglinzui的博客 883

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Session与进程组

在第 1 节 “信号的基本概念” 中我说过“Shell可以同时运行一个前台进程和任意多个后台进程”其实是不全面的,现在我们来研究更复杂的情况。事实上,Shell分前后台来控制的不是进程而是作业(Job)或者进程组(Process Group)。一个前台作业可以由多个进程组成,一个后台作业也可以由多个进程组成,Shell可以同时运行一个前台作业和任意多个后台作业,这称为作业控制(Job Contr

jibcy的专栏 2278

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

APUE 2 - 进程组(process group) 会话(session) job

进程组(process group) 进程组顾名思义是指一个或多个进程的集合。他们通常与同一个job(可以从同一个终端接收信号)相关联。每个进程组拥有一个唯一的Process Group Id。可以使用getpgrp或getpgid获取进程的Process Group Id: 1 #include <unistd.h> 2 3 /* 4 返回调用...

234

Linux进程关系:关于进程组和会话

会话是由其中的进程建立的,该进程叫做会话的领导进程(session leader)。进程组会有一个进程组领导进程 (process group leader),领导进程的PID (PID见Linux进程基础)成为进程组的ID (process group ID, PGID),以识别进程组。领导进程可以先终结。比如说,在Linux进程基础中,我们看到,每个进程都有父进程,而所有的进程以init进程为根,形成一个树状结构。PID为进程自身的ID,PGID为进程所在的进程组的ID, PPID为进程的父进程ID。.

xiaoweids的博客 671

进程、父进程、进程组ID、会话ID

   posix用一个session的概念来描述一次用户的登录以及该用户在此次登录后的操作,然后用作业的概念描述不同操作的内容,最后才用进程的概念描述不同操作中某一个具体的工作;其次,unix最初将所有的进程组织成了树的形式,这样就便于追踪每个进程也便于管理,有了上述两个前提事情就很明白了,一切都是为了便于管理,一切都是为了登录用户的安全,即此次登录用户的作业是不能被下个登录用户所控制的,即使它们...

勇于开拓 1997

linux 会话 进程组,Linux进程模型——会话和进程组

先放总结给没空看全文的人:session(会话)是用户登录系统以后所需的context(上下文)process group(进程组)是一组相关联的进程,用来方便信号量的分发session退出以后所有隶属于该session的进程组都会收到hup信号而挂起,这样就有了控制进程生命周期的作用tty可以作为输入输出设备被绑定到一个session上,bash就是这么干的子进程会继承父进程的session和p...

weixin_30336531的博客 433

linux 进程组 线程组,linux内核——会话、进程组、线程组

会话、进程组、线程组总体关系示意图待插入Session(会话)与进程组Shell 分前后台来控制的不是进程而是作业(Job)或者进程组(ProcessGroup)。一个前台作业可以由多个进程组成,一个后台作业也可以由多个进程组成,Shell可以同时运行一个前台作业和任意多个后台作业,这称为作业 控制(JobControl)。例如用以下命令启动5个进程(这个例子出自[APUE2e]):其中proc1...

weixin_30654137的博客 469

Linux 进程概念: thread group, process group, session

Linux,thread group,process group,session

JiMoKuangXiangQu的专栏 660

Linux进程管理:进程组、会话与守护进程实践

进程管理是操作系统核心功能,Linux通过进程组(PGID)和会话(SID)实现多任务隔离与控制。进程组将相关进程组织为作业控制单元,会话则建立终端环境隔离,二者配合实现前后台任务切换。守护进程通过fork-setsid双重调用脱离终端控制,是服务端程序的基础实现方式。理解这些机制对开发可靠后台服务至关重要,尤其在需要处理终端信号、权限控制和日志输出的场景。现代系统虽采用systemd等托管方案,但底层仍依赖这些基础概念,如容器化部署时仍需关注进程生命周期管理。

weixin_33853794的博客 414

进程的基本属性:进程ID、父进程ID、进程组ID、会话和控制终端

摘要:本文主要介绍进程的基本属性,基本属性包括:进程ID、父进程ID、进程组ID、会话和控制终端.

计算机视觉领域 6786

Linux进程关系-process group.session group

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢! Linux的进程相互之间有一定的关系。比如说,在Linux进程基础中,我们看到,每个进程都有父进程,而所有的进程以init进程为根,形成一个树状结构。我们在这里讲解进程组和会话,以便以更加丰富的方式了管理进程。 进程组 (process group) 每个进程都会属于一个...

toyijiu的专栏 1823

Linux--进程组、会话、守护进程

转:http://www.cnblogs.com/forstudy/archive/2012/04/03/2427683.html int setpgid(pid_t pid, pid_t pgid); pid_t getpgid(pid_t pid) pid_t getpgrp(void)//用来取得目前进程所属的组识别码。此函数相当于调用getpgid(0);返回目前进程所属的组识别码。...

365
上一篇: 【操作系统】MMAP内存映射|零拷贝
下一篇: 【Linux】孤儿进程|守护进程|Shell脚本设置守护进程开机自启
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值