/*
* function: 父进程使用sigaction()函数捕捉SIGCHLD信号子进程
*
* 2020-12-27
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
void func(int signo)
{
pid_t wpid;
int status;
while ((wpid = waitpid(-1, &status, 0)) != -1) // 阻塞回收, -1表示没有子进程
{
if (WIFEXITED(status))
{
printf("catch a child %d, normal exit status:%d\n", wpid, WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
printf("catch a child %d, kill by signal:%d\n", wpid, WTERMSIG(status));
}
else if (WCOREDUMP(status))
{
printf("catch a child %d, stop status:%d\n", wpid, WIFSTOPPED(status));
}
}
}
int main(int argc, char *argv[])
{
pid_t pid = 0;
// 阻塞SIGCHLD信号,防止在父进程注册捕捉函数之前子进程退出
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigprocmask(SIG_BLOCK, &set, NULL);
int ii = 0;
for (ii = 0; ii < 5; ++ii)
{
pid = fork();
if (0 == pid)
{
break; // 子进程跳出循环
}
else if (-1 == pid)
{
perror("fork failed");
exit(1);
}
}
if (pid > 0) // 父进程
{
printf("I'm parent:%d\n", getpid());
struct sigaction act;
act.sa_handler = func; // 设置回调函数
sigemptyset(&act.sa_mask); // 清空sa_mask
act.sa_flags = 0; // 设置默认属性
sigaction(SIGCHLD, &act, NULL); // 注册信号捕捉
// 解除阻塞
sigprocmask(SIG_UNBLOCK, &set, NULL);
while(1); // 模拟父进程后续操作
}
else if (0 == pid) // 子进程
{
printf("I'm a child:%d\n", getpid());
return ii;
}
return 0;
}
catch_child.cpp
最新推荐文章于 2024-09-07 23:15:53 发布