父进程可以在同一时间向所有子进程发送信号吗?

can a parent send signal to all child processes in the same exact time?

我正在尝试找出如何在同一秒内向 3 个子进程发送信号,您能否向我解释一下到底为什么可行或不可行?

如果可能的话,你能帮助我理解在 c 中使用 kill() 的一些代码吗?

TL;DR — 否

kill() 的 POSIX 规范提供了几种向多个进程发送信号的方法:

If pid is 0, sig shall be sent to all processes (excluding an unspecified set of system processes) whose process group ID is equal to the process group ID of the sender, and for which the process has permission to send a signal.

If pid is -1, sig shall be sent to all processes (excluding an unspecified set of system processes) for which the process has permission to send that signal.

If pid is negative, but not -1, sig shall be sent to all processes (excluding an unspecified set of system processes) whose process group ID is equal to the absolute value of pid, and for which the process has permission to send a signal.

您的请求是 'all children'。如果 children 中的任何一个更改了进程组 ID,那将是不可行的——这是他们可以随意做的事情。此外,如果 children 中的任何一个执行了 SUID 程序,您很可能已经失去了向他们发送信号的权限。

-1pid值相当危险;我相信它会转到与当前进程具有相同(有效)UID 的所有进程。

一个简单的解决方案是将所有子进程放在同一个进程组中,然后向该进程组发送信号。

示例代码:

#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 是不可行的 — 这是他们可以自由 do.Also 的事情,如果任何子进程从那以后执行了一个 SUID 程序,你可能已经失去了向他们发送信号的权限。

希望对您有所帮助。