实现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;

  }

}

 

posted @ 2020-03-03 18:58  路璐  阅读(1594)  评论(0编辑  收藏  举报