“代码 list 1”和“代码 list 2”有区别吗?因为在代码 list 1 中,子进程能够捕获 SIGTERM 信号并正常退出。但是代码 list 2 在收到 SIGTERM 信号时突然终止。
我正在使用 Linux 和 C。
代码 list 1
if (signal(SIGTERM, stopChild) == SIG_ERR) {
printf("Could not attach signal handler\n");
return EXIT_FAILURE;
}
pid = fork();
代码 list 2
pid = fork();
if (signal(SIGTERM, stopChild) == SIG_ERR) {
printf("Could not attach signal handler\n");
return EXIT_FAILURE;
}
奇怪的是,在代码 list 2 中,子进程和父进程都为 SIGTERM 设置了信号处理程序。所以,这应该有效。不是吗?
最佳答案
如果您从父级发送 SIGTERM,最终结果取决于进程的调度顺序。
如果 child 先被安排好,一切正常:
+---------------+
| pid = fork(); |
+-------+-------+
parent | child
+-----------------------------+-----------------------------+
| |
| +-------------------------+--------------------------+
| | if (signal(SIGTERM, stopChild) == SIG_ERR) { |
| | printf("Could not attach signal handler\n"); |
| | return EXIT_FAILURE; |
| | } |
| +-------------------------+--------------------------+
| |
. .
. .
. .
| |
+-------------------------+--------------------------+ |
| if (signal(SIGTERM, stopChild) == SIG_ERR) { | |
| printf("Could not attach signal handler\n"); | |
| return EXIT_FAILURE; | |
| } | |
+-------------------------+--------------------------+ |
| |
| |
| |
+-------------+-------------+ |
| if (pid > 0) { | |
| kill(pid, SIGTERM); | |
| } | |
+-------------+-------------+ |
| |
| |
| |
但是如果 parent 先被调度, child 可能没有时间设置信号处理程序:
+---------------+
| pid = fork(); |
+-------+-------+
parent | child
+-----------------------------+-----------------------------+
| |
+-------------------------+--------------------------+ |
| if (signal(SIGTERM, stopChild) == SIG_ERR) { | |
| printf("Could not attach signal handler\n"); | |
| return EXIT_FAILURE; | |
| } | |
+-------------------------+--------------------------+ |
| |
| |
| |
+-------------+-------------+ |
| if (pid > 0) { | |
| kill(pid, SIGTERM); | |
| } | |
+-------------+-------------+ |
| |
. .
. .
. .
| |
| +-------------------------+--------------------------+
| | if (signal(SIGTERM, stopChild) == SIG_ERR) { |
| | printf("Could not attach signal handler\n"); |
| | return EXIT_FAILURE; |
| | } |
| +-------------------------+--------------------------+
| |
| |
| |
这称为竞争条件,因为最终结果取决于谁先跑。
关于 fork 后调用信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4828603/