实现Linux父进程创建并使用信号回收多个子进程
/*
* main.c
* 子进程状态改变会发送SIGCHLD信号给父进程
* 此处实现父进程创建并回收多个子进程
* Created on: 2020年3月3日
* Author: LuYonglei
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <signal.h>
#define MY_PROCESS_COUNT 10
void child_catch(int signalNumber) {
//子进程状态发生改变时,内核对信号作处理的回调函数
int w_status;
pid_t w_pid;
while ((w_pid = waitpid(-1, &w_status, WNOHANG)) != -1 && w_pid != 0) {
if (WIFEXITED(w_status)) //判断子进程是否正常退出
printf("---catch pid %d,return value %d\n", w_pid, WEXITSTATUS(w_status)); //打印子进程PID和子进程返回值
}
}
int main(int argc, char **argv) {
pid_t pid;
int i;
//在此处阻塞SIGCHLD信号,防止信号处理函数尚未注册成功就有子进程结束
sigset_t child_sigset;
sigemptyset(&child_sigset); //将child_sigset每一位都设置为0
sigaddset(&child_sigset, SIGCHLD); //添加SIGCHLD位
sigprocmask(SIG_BLOCK, &child_sigset, NULL); //完成父进程阻塞SIGCHLD的设置
for (i = 0; i < MY_PROCESS_COUNT; i++) {
//创建子进程,创建成功就跳出循环
if ((pid = fork()) == 0)
break;
}
if (MY_PROCESS_COUNT == i) { //括号内为父进程代码
struct sigaction act; //信号回调函数使用的结构体
act.sa_handler = child_catch;
sigemptyset(&(act.sa_mask)); //设置执行信号回调函数时父进程的的信号屏蔽字
act.sa_flags = 0;
sigaction(SIGCHLD, &act, NULL); //给SIGCHLD注册信号处理函数
//解除SIGCHLD信号的阻塞
sigprocmask(SIG_UNBLOCK, &child_sigset, NULL);
printf("im PARENT ,my pid is %d\n", getpid());
while (1); //父进程堵塞,回收子进程
} else {
//子进程执行代码
printf("im CHILD ,my pid is %d\n", getpid());
return i;
}
}