The POSIX规范
system()函数将忽略SIGINT和SIGQUIT信号,并在等待命令终止时阻塞SIGCHLD信号。如果这可能导致应用程序丢失一个本来会杀死它的信号,那么应用程序应该检查system()的返回值,并在命令由于接收到信号而终止时采取对应用程序合适的任何操作。
这意味着启动长期运行的子进程的程序将被SIGINT和SIGQUIT阻塞很长时间。下面是在我的Ubuntu18.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..Then我可以看到,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试图用test_system杀死SIGINT没有效果。
$ kill -SIGINT 7489。。但是向进程组发送SIGINT确实会扼杀它(这是预期的,这意味着进程组中的每个进程都接收到信号--睡眠将退出,系统将返回)。
$ kill -SIGINT -7489
[1]+ Done ./test_system问题
SIGINT和SIGQUIT的目的是什么,因为进程仍然可以通过process组被杀死(这就是在终端中执行^C时发生的情况)。SIGCHLD?SIGINT和SIGQUIT被忽略以确保我们不会留下孩子,那么为什么SIGTERM没有处理--这是杀死发送的默认信号!发布于 2019-05-09 07:04:34
SIGINT和SIGQUIT是终端产生的信号。默认情况下,当您分别按Ctrl+C或Ctrl+\时,它们会被发送到前台进程组。
我认为,在通过system运行孩子时忽略它们的想法是,终端应该像临时由孩子拥有一样,而Ctrl+C或Ctrl+\应该暂时只影响孩子及其后代,而不是父母。
SIGCHLD被阻塞,因此如果您有一个SIGCHLD处理程序,那么由子终止引起的system的SIGCHLD不会触发一个SIGCHLD处理程序,因为这样的SIGCHLD处理程序可能会在system获取该子处理程序之前,就获得system启动的子处理程序。
https://stackoverflow.com/questions/56053355
复制相似问题