进程关系~

news/2024/4/29 5:45:15/文章来源:https://blog.csdn.net/weixin_50866517/article/details/126921790

进程关系

  • 一、进程组
    • 二、会话
    • 三、控制终端
    • 四、函数tcgetpgrp、tcsetpgrp和tcgetsid
    • 五、作业控制
    • 五、孤儿进程组

一、进程组

每个进程除了有一进程ID之外,还属于一个进程组,进程组是一个或多个进程的集合。同一进程组中的各进程接收来自同一终端的各 种信号。每个进程组有一个唯一的进程组ID。类似进程ID是个整数,存放pid_t数据类型。

#include <unistd.h>pid_t getpgrp(void); //返回值:调用进程的进程组ID
//带参数形式:
#include<unistd.h>
pid_t getgid(pid_t pid);
//pid为0,返回调用进程的进程组ID
getpgid(0);
//等价于
getpgrp();
  1. 每个进程组有一个组长进程。组长进程的进程组ID等于其进程ID。

  2. 进程组组长可以创建一个进程组、创建该组中的进程,然后终止。

  3. 只要在某个进程组中有一个进程存在,则该进程组就存在,这与其组长进程是否终止无关。

  4. 从进程组创建开始到其中最后一个进程离开为止的时间区间称为进程组 的生命期。

  5. 某个进程组中的最后一个进程可以终止,也可以转移到另一个进程 组。

//加入一个现有的进程组或者创建一个新进程组
int setpgid(pid_t pid, pid_t pgid);
//setpgid函数将pid进程的进程组ID设置为pgid。
//如果这两个参数相等,则由pid指定的进程变成进程组组长。
//pid是0,则使用调用者的进程ID。
//果pgid是0,则由pid指定的进程ID用作进程组ID。
//返回值:若成功,返回0;若出错,返回−1
  1. 一个进程只能为它自己或它的子进程设置进程组ID。在它的子进程调用了 exec后,它就不再更改该子进程的进程组ID。

  2. 在fork之后调用此函数,使父进程设置其子进程的进程组ID,并且也使子进程设置其自己的进程组ID。这两个调用中有个是 冗余的,但让父进程和子进程都这样做可以保证,在父进程和子进程认为子进 程已进入了该进程组之前,这确实已经发生了。

  3. 不这样做,在fork之后,由 于父进程和子进程运行的先后次序不确定,会因为子进程的组员身份取决于哪 个进程首先执行而产生竞争条件。

二、会话

会话是一个或多个进程组的集合,如下图所示一个会话中有3个进程组。

在这里插入图片描述

shell的管道将几个进程编程一组,上图可以有shell命令形成的:

procl | proc2 & 
proc3 | proc4 | proc5
//建立一个新会话。
#include <unistd.h> 
pid_t setsid(void); 
//返回值:若成功,返回进程组ID;若出错,返回-1

调用此函数的进程不是一个进程组的组长,则此函数创建一个新会 话。具体会发生以下3件事。

  1. 该进程变成新会话的会话首进程(session leader,会话首进程是创建 该会话的进程)。此时,该进程是新会话中的唯一进程。
  2. 该进程成为一个新进程组的组长进程。新进程组ID是该调用进程的进 程ID。
  3. 该进程没有控制终端。如果在调用 setsid 之 前该进程有一个控制终端,那么这种联系也被切断。
  • 如果该调用进程已经是一个进程组的组长,则此函数返回出错。

    • 通常先调用fork,然后使其父进程终止,而子进程则继续。

      • 因为子进程继承了父进程的进程组ID,而其进程ID则是新分配的,两者不可能相等,这就保证了子进程不是一个进程组的组长。
//getsid函数返回会话首进程的进程组ID
#include <unistd.h> 
pid_t getsid(pid_t pid); 
//若pid是0,getsid返回调用进程的会话首进程的进程组ID。
//若pid并不属于调用者所在的会话,那么调用进程就不能得到该会话首进程的进程组ID。
//返回值:若成功,返回会话首进程的进程组ID;若出错,返回-1

三、控制终端

会话和进程组还有一些其他特性

  1. 一个会话可以有一个控制终端。这通常是终端设备(在终端登录情况下)或伪终端设备(在网络登录情况下)。

  2. 建立与控制终端连接的会话首进程被称为控制进程。

  3. 一个会话中的几个进程组可被分成一个前台进程组以及一个或多个后台进程组。

  4. 如果一个会话有一个控制终端,则它有一个前台进程组,其他进程组为后 台进程组。

  5. 无论何时键入终端的中断键(常常是Delete或Ctrl+C),都会将中断信号 发送至前台进程组的所有进程。

  6. 无论何时键入终端的退出键(常常是Ctrl+\),都会将退出信号发送至前 台进程组的所有进程。

  7. 如果终端接口检测到调制解调器(或网络)已经断开连接,则将挂断信号 发送至控制进程(会话首进程)。

在这里插入图片描述
通常,我们不必担心控制终端,登录时,将自动建立控制终端,4个平台分配控制终端的方式:
在这里插入图片描述

  1. 不管标准输入、标准输出是否重定向,程序都要与控制终端交互作 用。

  2. 保证程序能与控制终端对话的方法是 open 文件/dev/tty。

  3. 程序没有控制终端,则对于此设备的 open将失败。

四、函数tcgetpgrp、tcsetpgrp和tcgetsid

//通知内核哪一个进程组是前台进程组
#include <unistd.h> 
pid_t tcgetpgrp(int fd);
//fd必须引用该会话的控制终端。
//函数tcgetpgrp返回前台进程组ID,它与在fd上打开的终端相关联。
//返回值:若成功,返回前台进程组ID;若出错,返回−1int tcsetpgrp(int fd, pid_t pgrpid); //进程有控制终端,则该进程可以调用tcsetpgrp将前台进程组ID设 置为pgrpid。//pgrpid值应当是在同一会话中的一个进程组的ID。// 返回值:若成功,返回0;若出错,返回−1
//给出控制TTY的文件描述符,通过tcgetsid函数,应用程序就能获得会话首进程的进程组ID。
#include <termios.h>pid_t tcgetsid(int fd);//返回值:若成功,返回会话首进程的进程组ID;若出错,返回−1//要管理控制终端的应用程序可以调用 tcgetsid 函数识别出控制终端的会话 首进程的会话ID(它等价于会话首进程的进程组ID)。

五、作业控制

作业控制,允许在一个终端上启动 多个作业(进程组),它控制哪一个作业可以访问该终端以及哪些作业在后台 运行。作业控制要求以下3种形式的支持。

  1. 支持作业控制的shell。

  2. 内核中的终端驱动程序必须支持作业控制。

  3. 内核必须提供对某些作业控制信号的支持。

如下图所示作业控制的功能,穿过终端驱动程序框的实线表明终端 I/O 和终端产生的信号总是从前台进程组连接到实际终端。对 应于 SIGTTOU 信号的虚线表明后台进程组进程的输出是否出现在终端是可选 择的。
在这里插入图片描述

五、孤儿进程组

  1. 父进程已终止的进程称为孤儿进程,这种进程由init进程“收养”。整个进程组也可成为“孤儿”。

  2. 进程fork了一个子进程然后终止,但是在父进程终止时,该子进程停止(用作业控制)又将如何呢?子进程如何继续,以及子进程是否知道它已经是孤儿进程?

下图显示:父进程已经fork了子进程,该子进程停止,父进程则将退出。

在这里插入图片描述
程序如下:

#include "apue.h"
#include <errno.h>static void sig_hup(int signo)
{printf("SIGHUP received, pid = %ld\n", (long)getpid());
}static void pr_ids(char *name)
{printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n",name, (long)getpid(), (long)getppid(), (long)getpgrp(),(long)tcgetpgrp(STDIN_FILENO));fflush(stdout);
}int main(void)
{char	c;pid_t	pid;pr_ids("parent");if ((pid = fork()) < 0) {err_sys("fork error");} else if (pid > 0) {	/* parent */sleep(5);	// 父进程睡眠5秒,这是一种让子进程在父进程终止之前运行的一种权宜之计 } else {			/* child */pr_ids("child");//子进程为挂断信号(SIGHUP)建立信号处理程序。//观察到 SIGHUP信号是否已发送给子进程signal(SIGHUP, sig_hup);	//建立信号处理程序
//子进程用kill函数向其自身发送停止信号(SIGTSTP)。kill(getpid(), SIGTSTP);	//停止pr_ids("child");	//只有当我们继续时才打印if (read(STDIN_FILENO, &c, 1) != 1)printf("read error %d on controlling TTY\n", errno);}//当父进程终止时,该子进程成为孤儿进程,所以其父进程ID成为1,也就是init进程ID。//现在,子进程成为一个孤儿进程组的成员exit(0);
}

假定使用了一个作业控制 shell,shell 将前台进程放在它 (指前台进程)自已的进程组中(本例中是6099),shell则留在自己的进程组内(2837)。子进程继承其父进程(6099)的进程组。在fork之后:

父进程终止后,进程组包含一个停止的进程,进程组成为孤儿进程组,POSIX.1要求向新孤儿进程组中处于停止状态的每一个进程发送挂断信号 (SIGHUP),接着又向其发送继续信号(SIGCONT)。在处理了挂断信号后,子进程继续。

对挂断信号的系统默认动作是终止该进程,为此必须提供一个信号处理程序以捕捉该信号。因此,我们期望sig_hup 函数中的printf会在pr_ids函数中的printf之前执行。

POSIX.1将孤儿进程组定义为:

  1. 该组中每个成员的父进程要么是该组的一个 成员,要么不是该组所属会话的成员。

  2. 一 个进程组不是孤儿进程组的条件是——该组中有一个进程,其父进程在属于同 一会话的另一个组中。如果进程组不是孤儿进程组,那么在属于同一会话的另 一个组中的父进程就有机会重新启动该组中停止的进程。

  3. 进程组中每 一个进程的父进程(例如,进程6100的父进程是进程1)都属于另一个会话,所以此进程组是孤儿进程组。

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Eclipse2022创建SSM项目及问题解决

Eclipse2022创建SSM项目及问题解决 使用Eclipse创建SSM项目的过程中会遇到一些问题&#xff0c;相对于IDEA而言更为繁琐&#xff0c;该篇文章是在使用Eclipse2022&#xff0c;并且设备上已经安装、配置好了Tomcat和Maven的基础之上进行的&#xff0c;目的是为了记录在Eclipse上…

Windows部署JMeter的压力测试

1.安装Windows版本Java 直接下载Java exe格式程序包 官网下载 点击 2.下载JMeter的压缩包 官网下载地址请 点击 或者复制这个URL: https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.5.tgz 在浏览器上&#xff0c;会自动下载 下载下来解压即可。 3.启动JMeter 进入…

Linux内核设计与实现 第十二章 内存管理

因为内核内存需要节省着用&#xff0c;内核处理内存分配错误比较麻烦等&#xff0c;所以内核中获取内存不用户空间获取内存复杂得多。 本章讨论内核是如何管理内存和内核之中获取内存的办法。 12.1页 a) 可以通过 getconf 命令来查看系统的page的大小&#xff1a; [wangyubi…

Linux开发_CentOS7.4服务器安装NFS、NGINX服务器,ffmpeg、Qt环境

1. 环境介绍 环境介绍&#xff1a;采用的是华为云的ECS弹性云服务器–镜像安装的CentOS7.4 64位 -----是服务器版&#xff0c;非桌面版哦。 在CentOS7.4服务器版本的环境下搭建NFS服务器、安装ffmpeg、安装nginx服务器、部署Qt编译环境。 &#xff08;1&#xff09;配置NGIN…

河北稳控科技几种振弦采集仪的主要区别是什么?

河北稳控科技几种振弦采集仪的主要区别是什么?VH系列属于手持系列,多用于振弦传感器现场单次测量使用;VH501TC采集读数仪,设备是专用的多类型传感器手持式读数仪,主测传感类型为单弦式振弦传感器,辅测传感类型为电压、电流传感。采用 32 位 ARM 处理器和大尺寸全彩屏、阵…

无人机群编队分析的定位问题 分析与思考-1(数学建模竞赛2022年B题)

2022年高教社杯全国大学生数学建模竞赛结束了&#xff0c;在此我们对 2022年 B题 进行一些分析与思考。 1. 初步印象 2022年 B题 &#xff08;无人机遂行编队飞行中的纯方位无源定位&#xff09;是一个有趣的题目。 随着无人机技术的快速发展&#xff0c;早已从高科技变做寻常…

【Java】运算符

我不去想是否能够成功 既然选择了远方 便只顾风雨兼程 —— 汪国真 目录 1. 认识运算符 1.1 认识运算符 1.2 运算符的分类 2. 算术运算符 2.1 四则运算符 2.2 复合赋值运算符 2.3 自增 / 自减 运算符 3.关系运算符 4.逻辑运算符 4.1 逻辑与 && 4.2 逻…

分库分表实践

分库分表实践 分库分表概念以及使用场景 分库分表用来解决单表数据量太大&#xff0c;引起的性能问题。使用分库分表后能够根据特定路由键值将数据分布在不同库以及不同表中&#xff0c;解决了单表数据量的性能、运维等问题。一般来讲&#xff0c;单一数据库实例的数据的阈值…

【网络】HTTP协议详解

&#x1f600;大家好&#xff0c;我是白晨&#xff0c;一个不是很能熬夜&#x1f62b;&#xff0c;但是也想日更的人✈。如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下&#x1f440;白晨吧&#xff01;你的支持就是我最大的动力&#xff01;&#x1f4…

svn 代码迁入gitlab

window中安装好git客户端,右键空白处,点选git bash here进入git界面,输入命令 将svn38163之后的所有记录都备份那:git svn clone -r 38163:HEAD svn地址 --no-metadata trunk(本地电脑目录名) --username *** 备份所有提交记录:git svn clone svn地址 --no-metadata …

Linux安装Python 以及过程中的命令详细介绍

下载源码包 打开 Python 官网 找到需要的安装包 获取了资源的链接后&#xff0c;进入Linux下载&#xff0c;wget意思是webget&#xff0c; 即下载 wget https://www.python.org/ftp/python/3.10.7/Python-3.10.7.tgz目录下会新增 这样源码包就下载好了。 如果下载太慢&…

二叉树与递归问题

目录 一&#xff1a;求二叉树的深度 二&#xff1a;二叉树反转 三&#xff1a;二叉树镜像判断 四&#xff1a;递归的终止条件 用递归解决的问题必须注意的&#xff1a; 递归的终止条件&#xff0c;也就是递归的出口&#xff08;否则&#xff1a;栈溢出&#xff09;递归的过…

决策树简介

决策树简介 决策树实际上是一个布尔函数,它的输出可以是“0 或 1”或“-1 或 +1”或“-1、0 或 +1”。决策树的大小等于其中存在的节点数,其深度等于从顶部到根的最长路径的长度。 错误率:训练集始终是给模型的标记示例,模型训练得越多,其错误率就越低。 训练样本 = { set…

程序里对象很深很大,可以用这个设计模式缓解一下

如果一个类的有非常多的属性&#xff0c;层级还很深。这个妥妥的是我的对象很大&#xff0c;你创建的时候忍一下......那你每次要创建的时候都忍一下&#xff1f;有没有一种好的方式让我们创建太的时候使用体验更好一点呢? 今天的文章里就给大家介绍一种设计模式&#xff0c;来…

C++多线程的线程返回值问题

对于多线程可执行对象的返回值是何时返回&#xff0c;以及得到的呢&#xff1f; 对于需要用到线程返回值的线程要使用future类对象来实现 文章目录future对象async()launch::deferred参数launch::async参数packaged_taskpromisefuture对象 是一个类模板 提供访问异步对象的操作…

优化 | Management Science 7-8月文章精选: 信息系统中的运筹学

作者&#xff1a;Evelyn Yao 清华大学本科在读 在“Management Science近期论文精选”中&#xff0c;我们有主题、有针对性地选择了Management Science中一些有趣的文章&#xff0c;不仅对文章的内容进行了概括与点评&#xff0c;而且也对文章的结构进行了梳理&#xff0c;旨在…

非零基础自学Java (老师:韩顺平) 第13章 常用类 13.5 StringBuffer类

非零基础自学Java (老师&#xff1a;韩顺平) ✈【【零基础 快速学Java】韩顺平 零基础30天学会Java】 第13章 常用类 文章目录非零基础自学Java (老师&#xff1a;韩顺平)第13章 常用类13.5 StringBuffer类13.5.1 基本介绍13.5.2 String VS StringBuffer13.5.3 String 和 Str…

HashMap

1.HashMap集合 1.1HashMap集合概述和特点【理解】 HashMap底层是哈希表结构的依赖hashCode方法和equals方法保证键的唯一如果键要存储的是自定义对象&#xff0c;需要重写hashCode和equals方法 1.2 特点 HashMap是线程不安全的实现&#xff1b; HashMap可以使用null作为key…

【Pytorch深度学习实战】(9)神经语言模型(RNN-LM)

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

第一视角体验搭载全志T507-H的开发板MYD-YT507H开发板

如今车规级芯片市场潜力巨大&#xff0c;需求旺盛&#xff0c;芯片都在逐渐走向国产化。本文要介绍的主角是MYD-YT507H开发板&#xff0c;该开发板是米尔科技结合全志国产工业级平台CPU——全志T507-H芯片研制的CPU模组&#xff0c;全志T507-H可广泛用于电力物联网、汽车电子、…