C语言 父进程能否在同一时间向所有子进程发送信号?

fzsnzjdm  于 2023-03-01  发布在  其他
关注(0)|答案(2)|浏览(144)

我想知道如何在一秒钟内向3个子进程发送一个信号,你能给我解释一下为什么这是可能的,或者是不可能的吗?
如果可能的话,你能帮助我理解使用kill()的一些C代码吗?

k2fxgqgv

k2fxgqgv1#

TL;DR -否

kill()的POSIX规范给出了几种向多个进程发送信号的方法:
如果 pid 为0,则将 sig 发送给进程组ID等于发送方进程组ID的所有进程(不包括未指定的一组系统进程),并且该进程具有发送信号的权限。
如果 pid 为-1,则 sig 应发送到所有进程(不包括未指定的系统进程集),该进程有权向这些进程发送该信号。
如果 pid 为负,但不为-1,则 sig 将发送给进程组ID等于 pid 绝对值的所有进程(不包括未指定的系统进程集),并且该进程有权限发送信号。
您的请求是针对“所有子进程”的。如果任何子进程更改了进程组ID,这是不可行的,而这是他们可以自由执行的操作。此外,如果任何子进程此后执行了SUID程序,您很可能已经失去了向他们发送信号的权限。
-1pid 值相当危险;我相信它会转到与当前进程具有相同(有效)UID的所有进程。

r55awzrz

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程序,您很可能已经失去了向他们发送信号的权限。
希望这对你有帮助。

相关问题