我正在编写一个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);
}
答案 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);
}