在等待命令终止时,system()函数将忽略SIGINT和SIGQUIT信号,并阻塞SIGCHLD信号。如果这可能导致应用程序丢失可能杀死该信号的信号,则该应用程序应检查system()的返回值,并在命令由于接收到信号而终止时对应用程序采取适当的操作。 >
这意味着启动长时间运行的子进程的程序将长时间阻塞SIGINT
和SIGQUIT
。这是在我的Ubuntu 18.10笔记本电脑上编译的测试程序:
$ cat > test_system.c <<< EOF
#include <stdlib.h>
int main() {
system("sleep 86400"); // Sleep for 24 hours
}
EOF
$ gcc test_system.c -o test_system
如果我启动在后台运行的测试程序...
$ ./test_system &
[1] 7489
..然后我可以看到SIGINT
(2)和SIGQUIT
(3)在位掩码中被标记为已忽略。
$ ps -H -o pid,pgrp,cmd,ignored
PID PGRP CMD IGNORED
6956 6956 -bash 0000000000380004
7489 7489 ./test_system 0000000000000006
7491 7489 sh -c sleep 86400 0000000000000000
7492 7489 sleep 86400 0000000000000000
尝试使用SIGINT
杀死test_system无效。
$ kill -SIGINT 7489
..但是将SIGINT
发送到进程组确实会杀死它(这是预期的,这意味着进程组中的每个进程都会收到信号-睡眠将退出,系统将返回)。
$ kill -SIGINT -7489
[1]+ Done ./test_system
SIGINT
和SIGQUIT
的目的是什么,因为仍然可以通过进程组杀死该进程(在终端中执行^C
时会发生这种情况)。 SIGCHLD
被阻止?SIGINT
和SIGQUIT
以确保我们不会把孩子丢在后面,那么为什么SIGTERM
没有处理-这就是杀死发送的默认信号!答案 0 :(得分:1)
SIGINT
和SIGQUIT
是终端生成的信号。默认情况下,当您分别按下Ctrl+C
或Ctrl+\
时,它们将被发送到前台进程组。
我相信在通过system
抚养孩子时忽略他们的想法是,终端应该好像它是孩子的临时所有者,Ctrl+C
或Ctrl+\
应该只是暂时的影响孩子及其后代,而不是父母。
SIGCHLD
被阻止,以使system
是由子终止引起的SIGCHLD
(如果有)将不会触发SIGCHLD
处理程序,因为这样的{ {1}}处理程序可能会在SIGCHLD
之前收获由system
开始的孩子。