在发送信号之前,我怎么知道是否已经创建了所有进程?

时间:2016-12-07 23:17:27

标签: c

我正在编写一个Unix程序,其中父进程必须向子项和孙子发送信号。在发送信号之前,我怎么知道是否已经创建了所有进程?因为有时他们还不存在。非常感谢!

void t(int sig)
{
   kill(SIGKILL, pidc1);
   kill(SIGKILL, pidc2);
   kill(SIGKILL, pidg2);
   kill(SIGKILL, pidc3);
}

void handler()
{
    write(1, "Signal SIGUSR1\n", 15);
}

pid_t pidc1, pidc2, pidc3, pidg2;

int main(int argc, char **argv)
{
    struct sigaction action;
    int status;

    action.sa_flags = 0;
    action.sa_handler = handler;
    sigaction(SIGUSR1, &action, NULL);

    pidc1 = fork();
    if(pidc1 == 0)
    {
        printf("Child 1\n");
    }
    pidc2 = fork();
    if(pidc2 == 0)
    {
         printf("Child 2\n");
         pidg2 = fork();
         if(pidg2 == 0)
         {
             printf("Grandson 2\n");
         }
         wait(&status);
    }
    pidc3 = fork();
    if(pidc3 == 0)
    {
        printf("Child 3\n");
    }

    kill(pidg2, SIGUSR1);
    kill(pidc3, SIGUSR1);
    signal(SIGALRM, t);
    alarm(10);
    wait(&status);
}

1 个答案:

答案 0 :(得分:0)

初步说明:示例程序中的子代码部分属于其父代码,这当然不是有意的;我会在每个块的末尾假设return sleep(5);之类的东西。另请注意,printf()可能会因fork() s和缓冲输出而出现故障。

Barmar写道:

  

如果您需要等待创建孙子进程,您需要从子进程到父进程的某种通信,因此它可以发送孙子的PID。共享内存和互斥锁是一种方法。

这是绝对正确的。 (直接子节点没有问题,因为父节点知道它们的PID。)另一种传达孙子PID的方法是管道;您的示例main()可能会变为:

int main(int argc, char **argv)
{
    int status;
    sigaction(SIGUSR1, &(struct sigaction){.sa_handler = handler}, NULL);
    setbuf(stdout, NULL);   // printf() may malfunction without this
    pidc1 = fork();
    if (pidc1 == 0)
    {
        printf("Child 1\n");    return sleep(5);
    }
    int pipefd[2];
    pipe(pipefd);   // for communicating the grandson's PID
    pidc2 = fork();
    if (pidc2 == 0)
    {
         printf("Child 2\n");
         pidg2 = fork();
         if (pidg2 == 0)
         {
             printf("Grandson 2\n");   return sleep(5);
         }
         write(pipefd[1], &pidg2, sizeof pidg2);    // write pidg2 to write end
         wait(&status);    return sleep(5);
    }
    pidc3 = fork();
    if(pidc3 == 0)
    {
        printf("Child 3\n");    return sleep(5);
    }
    read(pipefd[0], &pidg2, sizeof pidg2);  // read pidg2 from pipe's read end
    kill(pidg2, SIGUSR1);
    kill(pidc3, SIGUSR1);
}