我想编写一个程序,其中父级恰好创建了一个子进程。子进程应将其pid打印到标准输出,然后完成。父进程应等待直到确定子进程已终止。父级在等待子级进程后终止。
那是我到目前为止所得到的:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int child;
child = fork();
if (child == 0)
{
printf("Child process has PID: %d. \n", getpid());
exit(0);
}
// how can the parent process find out it the child process was terminated successful?
printf("Child process terminated successfully\n");
return EXIT_SUCCESS;
}
父进程如何找出子进程是否终止?我不能在此程序中使用wait()或waitpid()。
感谢您的帮助!
答案 0 :(得分:2)
当子进程终止时,SIGCHLD信号将发送到父级,默认情况下,父级将忽略SIGCHLD,但是您可以注册一个捕获该信号的信号处理程序。
您需要小心在信号处理程序中执行的操作-很多标准函数不安全使用。
当父级有自己的工作要做而不能仅仅等待子级时,SIGCHLD方法就会出现在代码中。如果父母只生了孩子,然后等待他们完成,则wait()和waitpid()是最好的解决方案。
最后,如果您不调用wait()或waitpid(),则冒着创建一个僵尸进程的风险,子进程希望它的父进程通过调用以下函数之一来接收其退出状态。
答案 1 :(得分:1)
正如我在发言中所说,请使用信号 SIGCHLD ,例如:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void handler(int sig)
{
pid_t chpid = wait(NULL);
/* WARNING : to show the call of the handler, do not do that
in a 'real' code, we are in a handler of a signal */
printf("Child pid %d ended (signal %s)\n", chpid, sig);
/* does 'something' to allow the parent to know chpid
terminated in a way compatible with parent requirement */
}
int main(void)
{
signal(SIGCHLD, handler);
if (!fork())
{
printf("Child pid is %d\n", getpid());
sleep(1);
return 0;
}
printf("Parent pid is %d\n", getpid());
getchar();
return 0;
}
请注意,当信号到达时,您必须调用 wait(NULL),但是由于定义终止子函数会立即返回
编译和执行:
pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra s.c
pi@raspberrypi:/tmp $ ./a.out
Parent pid is 21743
Child pid is 21744
Child pid 21744 ended (signal 17)
<enter>
pi@raspberrypi:/tmp $
当然信号17是 SIGCHLD ,因为它是程序捕获的唯一信号