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

时间:2018-03-09 00:43:23

标签: c process signals parent-child kill

我试图找出如何以相同的精确分数向3个子进程发送信号,你能否向我解释为什么如果它可能或不可能?

如果有可能,你可以帮我理解在c中使用kill()吗?

2 个答案:

答案 0 :(得分:2)

TL; DR - 否

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

  

如果 pid 为0,则 sig 应发送到进程组ID等于进程组ID的所有进程(不包括未指定的系统进程集)发件人,并且该进程有权发送信号。

     

如果 pid 为-1,则 sig 将被发送到进程有权发送该信号的所有进程(不包括未指定的系统进程集)。

     

如果 pid 为负数,但不为-1,则应将 sig 发送给进程组ID等于的所有进程(不包括未指定的系统进程集) pid 的绝对值,并且该进程有权发送信号。

您的要求是针对所有孩子的#39;。如果任何一个孩子改变了过程组ID,这是不可行的 - 这是他们可以随意做的事情。此外,如果任何一个孩子已经执行了SUID程序,您可能已经失去了向他们发送信号的许可。

-1 pid 值非常危险;我相信它将使用与当前进程相同(有效)的UID进入所有进程。

答案 1 :(得分:0)

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

示例代码:

#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程序,你可能已经失去了向他们发送信号的许可。

希望这会对你有所帮助。