我想知道如何在一秒钟内向3个子进程发送一个信号,你能给我解释一下为什么这是可能的,或者是不可能的吗?如果可能的话,你能帮助我理解使用kill()的一些C代码吗?
kill()
k2fxgqgv1#
kill()的POSIX规范给出了几种向多个进程发送信号的方法:如果 pid 为0,则将 sig 发送给进程组ID等于发送方进程组ID的所有进程(不包括未指定的一组系统进程),并且该进程具有发送信号的权限。如果 pid 为-1,则 sig 应发送到所有进程(不包括未指定的系统进程集),该进程有权向这些进程发送该信号。如果 pid 为负,但不为-1,则 sig 将发送给进程组ID等于 pid 绝对值的所有进程(不包括未指定的系统进程集),并且该进程有权限发送信号。您的请求是针对“所有子进程”的。如果任何子进程更改了进程组ID,这是不可行的,而这是他们可以自由执行的操作。此外,如果任何子进程此后执行了SUID程序,您很可能已经失去了向他们发送信号的权限。-1的 pid 值相当危险;我相信它会转到与当前进程具有相同(有效)UID的所有进程。
-1
r55awzrz2#
一个简单的解决方案是将所有子进程放在同一个进程组中,并向该进程组发送信号。
#include <stdio.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> static volatile sig_atomic_t got_signal; void handler(int sig) { printf("caught signal: %d\n", getpid()); got_signal = 1; } int main() { pid_t child; pid_t children[3]; int status; int i = 0; signal(SIGINT, handler); for (; i < 3; i++) { switch (child = fork()) { case -1: perror("could not create child: "); break; case 0: printf("child: %d\n", getpid()); while (!got_signal); _exit(0); default: children[i] = child; /*put all children in process group of eldest child*/ setpgid(child, children[0]); } } sleep(1); /* send signal to all child by sending signal to process group of eldest child */ kill(-children[0], SIGINT); waitpid(children[0], &status, 0); waitpid(children[1], &status, 0); waitpid(children[2], &status, 0); exit(0); } gcc x.c ./a.out child: 1893 child: 1894 child: 1895 caught signal: 1895 caught signal: 1894 caught signal: 1893
但是正如@Jonathna所说,如果任何一个子进程更改了进程组ID,这是不可行的--这是他们可以自由做的事情。此外,如果任何一个子进程后来执行了SUID程序,您很可能已经失去了向他们发送信号的权限。希望这对你有帮助。
2条答案
按热度按时间k2fxgqgv1#
TL;DR -否
kill()
的POSIX规范给出了几种向多个进程发送信号的方法:如果 pid 为0,则将 sig 发送给进程组ID等于发送方进程组ID的所有进程(不包括未指定的一组系统进程),并且该进程具有发送信号的权限。
如果 pid 为-1,则 sig 应发送到所有进程(不包括未指定的系统进程集),该进程有权向这些进程发送该信号。
如果 pid 为负,但不为-1,则 sig 将发送给进程组ID等于 pid 绝对值的所有进程(不包括未指定的系统进程集),并且该进程有权限发送信号。
您的请求是针对“所有子进程”的。如果任何子进程更改了进程组ID,这是不可行的,而这是他们可以自由执行的操作。此外,如果任何子进程此后执行了SUID程序,您很可能已经失去了向他们发送信号的权限。
-1
的 pid 值相当危险;我相信它会转到与当前进程具有相同(有效)UID的所有进程。r55awzrz2#
一个简单的解决方案是将所有子进程放在同一个进程组中,并向该进程组发送信号。
但是正如@Jonathna所说,如果任何一个子进程更改了进程组ID,这是不可行的--这是他们可以自由做的事情。此外,如果任何一个子进程后来执行了SUID程序,您很可能已经失去了向他们发送信号的权限。
希望这对你有帮助。