查阅了几个小时关于 SIGCHLD 和 exit()相关的文章、Linux 守护进程 daemon 相关的文章之后。 现在有个疑惑。就是 SIGCHLD 到底是谁发出的?进而如果需要无视该信号,那么 signal(SIGCHLD,SIG_IGN)是要写在父进程中,还是被新建的 daemon 进程中??
这方面不太了解,网上查了 7-10 篇文章,感觉可能我语文阅读能力有问题?总感觉没有人说清楚这个 SIGCHLD 到底到底是哪里出现,最后又会被谁接收?
1
ashiamd OP 附上几篇看到的文章中比较标志性的,比如[创建守护进程为什么要 fork 两次]( https://blog.csdn.net/dream_1996/article/details/73467969)下方 "(6)其他:忽略 SIGCHLD 信号"的代码,我不是很懂为为什么是需要在新建出来的 daemon 进程执行 signal(SIGCHLD,SIG_IGN),这个 SIGCHLD 不应该是内核发送给父进程的吗?为什么反而是在子进程中声明无视 SIGCHLD ??
|
2
ashiamd OP 附上几篇看到的文章中比较标志性的。
比如[创建守护进程为什么要 fork 两次]( https://blog.csdn.net/dream_1996/article/details/73467969) "(6)其他:忽略 SIGCHLD 信号"的代码,我不是很懂为为什么是需要在新建出来的 daemon 进程执行 signal(SIGCHLD,SIG_IGN)。 这个 SIGCHLD 不应该是内核发送给父进程的吗?为什么反而是在子进程中声明无视 SIGCHLD ?? |
3
Nitroethane 2020-08-13 07:57:48 +08:00 via iPhone 1
当一个进程得子进程退出时,其父进程会收到 SIGCHLD 信号。调用 signal(SIGCHLD, SIG_IGN) 的目的是避免在父进程提前退出的情况下,子进程退出时不会变成 zombie 。
至于你说的那篇文章中调用 signal 函数,应该跟创建 daemon 进程没多大关系 |
4
feather12315 2020-08-13 08:39:26 +08:00 via Android 1
Q1:SIGCHLD 是子进程在进行 exit 系统调用的时候,在子进程的执行逻辑中子进程向父进程的 PCB 中添加的一个标志。有专门的函数进行这一逻辑。
Q2:SIGHUB 在执行 exit 系统调用的过程中出现,被父进程接收。比如三个进程,1 是 2 的子进程,2 是 3 的子进程,当 2 退出后,1 号的父进程变为 3,1 号的 SIGCHLD 发送给 3 号。 |
5
ashiamd OP @feather12315
@Nitroethane 昨晚深夜 找了不少 google 上的 wiki 什么的,好像也比较直观的说法。下午又下载 glib-c 的 C 代码,可惜没怎么看懂。 然后刚才看到一篇对 SIGCHLD 有代码示例的文章 ==>[ [Linux]关于 SIGCHLD ]( https://blog.csdn.net/xxpresent/article/details/73028750) 我按着里面的代码,在 Linux 服务器上,移动了 `signal(SIGCHLD,myhandler);` 这一句的位置;写几份 C 代码运行看效果 (1 )没移动,按文章那样,应该 父 /子进程 都等于 受到了这句函数最后导致的 PCB 变化等影响。有输出 sig (2 ) 移动到`if( id == 0)` 条件语句块里,子进程范围, 没有输出 sig (3) 移动到 `else` 条件语句块里,原进程(父进程)范围,有输出 sig 。 ------------------------------- 以上,结合我之前所学。我认为 SIGCHLD,是 exit()中的_exit()像操作系统 注册了 SIGCHLD 的 handler,要求当前进程执行 exit()内的逻辑时,要求内核向父进程通知 SIGCHLD 。而操作系统内部默认对 SIGCHLD 采取动作为忽略==>这个我认为是指 C 库代码里有对一些 SIG 系列信号预设了处理函数 handler,其中如果一个进程收到 SIGCHLD 信号,那么默认触发 C 库里面自动忽略 该信号的逻辑。==> 也就是 除非 父进程主动写 signal(SIGCHLD,自定义 handler 函数),来处理子进程 C 库代码预设的 exit()逻辑中要求内核向父进程发送的 SIGCHLD 信号;否则父进程其实收到 SIGCHLD 就直接调用 C 库里逻辑,忽略 SIGCHLD 信号了。 不知道这样说对不对? |
6
julyclyde 2020-08-14 23:56:41 +08:00 via iPad 1
信号从概念上并不重视谁发出的啊
|
7
julyclyde 2020-08-14 23:58:25 +08:00 via iPad
子进程无视 child 信号,主要是为了清除从父进程继承过来的 handler 避免副作用吧?
|