《UNIX环境高级编程》笔记--孤儿进程组

2024-04-14 21:58

本文主要是介绍《UNIX环境高级编程》笔记--孤儿进程组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

POSIX.1将孤儿进程组定义为:该组中每个成员的父进程要么是该组的一个成员,要么不是该组所属会话的成员。一个进程组

不是孤儿进程组的条件是:该组中有一个进程,其父进程在属于同一会话中的另一个组中。

下面对孤儿进程组的产生进行检验:

1.在一个具有作业控制的shell中,执行一个程序,该程序fork了一个子进程,其进程结构如下:


2.父进程休眠5秒钟,这是一种让子进程在父进程终止前运行的一种权宜之计。

3.子进程为挂断信号(SIGHUP)建立信号处理程序。这样就能观察到SIGHUP信号是否已发送到子进程。

4.子进程用kill函数向其自身发送停止信号(SIGTSTP)。这停止了子进程,类似于用终端挂起字符(ctrl+z)停止了一个前台作业。

5.当父进程终止时,该子进程成为了孤儿进程,所以其符进程成为1,也就是init进程ID。同时子进程成为了一个孤儿组的成员。

6.在父进程终止后,进程组成为孤儿进程组,POSIX.1要求向新的孤儿进程组中处于停止状态的每一个进程发送挂断信号

(SIGHUP),接着又向其发送继续信号(SIGCONT)。


程序:

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>static void sig_hup(int signo){printf("SIGHUP revevied, pid=%d\n",getpid());
}static void pr_ids(char *name){printf("%s:pid=%d,ppid=%d,pgrp=%d,tpgrp=%d\n",name,getpid(),getppid(),getpgrp(),tcgetpgrp(STDIN_FILENO));fflush(stdout);
}int main(void){char c;pid_t pid;pr_ids("parent");if((pid=fork())<0){perror("fork");return -1;}else if(pid > 0){sleep(5);exit(0);}else{pr_ids("child");signal(SIGHUP,sig_hup);kill(getpid(),SIGTSTP);pr_ids("child");if(read(STDIN_FILENO,&c,1) != 1){printf("read error from controlling tty, errno=%d\n",errno);}exit(0);}return 0;
}
运行结果:

yan@yan-vm:~/apue$ ./a.out
parent:pid=9154,ppid=9066,pgrp=9154,tpgrp=9154
child:pid=9155,ppid=9154,pgrp=9154,tpgrp=9154
yan@yan-vm:~/apue$ SIGHUP revevied, pid=9155
child:pid=9155,ppid=1,pgrp=9154,tpgrp=9066
read error from controlling tty, errno=5

一开始父进程和子进程在同一个进程组,父进程是前台进程组的首进程,所以前台进程组的进程组ID是父进程组ID。

子进程向自己发送了SIGTSTP信号,所以进程停止,当父进程结束后,子进程称为了孤儿进程,子进程所在的进程组称为了孤儿

进程组,POSIX.1要求向新的孤儿进程组中处于停止状态的每一个进程发送挂断信号(SIGHUP),所以子进程显示接受到了

SIGHUP信号,然后又接收到了继续信号(SIGCONT),子进程继续运行,然后打印了他的进程信息,此时父进程变成了1.

最后调用read,posix规定,在这种情况下,read返回错,并将errno设置为5(EIO)。

要注意的是,父进程终止时,子进程被置入后台进程组中,因为父进程是由shell作为前台作业执行的。

这篇关于《UNIX环境高级编程》笔记--孤儿进程组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/904125

相关文章

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

Java中的for循环高级用法

《Java中的for循环高级用法》本文系统解析Java中传统、增强型for循环、StreamAPI及并行流的实现原理与性能差异,并通过大量代码示例展示实际开发中的最佳实践,感兴趣的朋友一起看看吧... 目录前言一、基础篇:传统for循环1.1 标准语法结构1.2 典型应用场景二、进阶篇:增强型for循环2.

使用Python进行GRPC和Dubbo协议的高级测试

《使用Python进行GRPC和Dubbo协议的高级测试》GRPC(GoogleRemoteProcedureCall)是一种高性能、开源的远程过程调用(RPC)框架,Dubbo是一种高性能的分布式服... 目录01 GRPC测试安装gRPC编写.proto文件实现服务02 Dubbo测试1. 安装Dubb

python常见环境管理工具超全解析

《python常见环境管理工具超全解析》在Python开发中,管理多个项目及其依赖项通常是一个挑战,下面:本文主要介绍python常见环境管理工具的相关资料,文中通过代码介绍的非常详细,需要的朋友... 目录1. conda2. pip3. uvuv 工具自动创建和管理环境的特点4. setup.py5.