zoukankan      html  css  js  c++  java
  • SIGCHLD

    SIGCHLD的产生条件

      子进程终止时

      子进程接收到SIGSTOP信号停止时

      子进程处在停止态,接受到SIGCONT后唤醒时

    借助SIGCHLD信号回收子进程

    子进程结束运行其父进程会收到SIGCHLD信号该信号的默认处理动作是忽略可以捕捉该信号在捕捉函数中完成子进程状态的回收

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <signal.h>
    
    void sys_err(char *str)
    {
        perror(str);
        exit(1);
    }
    void do_sig_child(int signo)
    {
        int status;    pid_t pid;
        while ((pid = waitpid(0, &status, WNOHANG)) > 0) {
            if (WIFEXITED(status))
                printf("child %d exit %d
    ", pid, WEXITSTATUS(status));
            else if (WIFSIGNALED(status))
                printf("child %d cancel signal %d
    ", pid, WTERMSIG(status));
        }
    }
    int main(void)
    {
        pid_t pid;    int i;
        for (i = 0; i < 10; i++) {
            if ((pid = fork()) == 0)
                break;
            else if (pid < 0)
                sys_err("fork");
        }
        if (pid == 0) {    
            int n = 1;
            while (n--) {
                printf("child ID %d
    ", getpid());
                sleep(1);
            }
            return i+1;
        } else if (pid > 0) {

          //这里还应对SIGCHLD进行阻塞  防止父进程SIGCHLD还未注册完成子进程就已经死亡
    struct sigaction act; act.sa_handler = do_sig_child; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGCHLD, &act, NULL);   //解除阻塞 while (1) { printf("Parent ID %d ", getpid()); sleep(1); } } return 0; }

    上述代码若将do_sig_child(),SIGCHLD信号处理函数改为:

    void do_sig_child(int signo)
    {
        int status;    pid_t pid;
        if((pid = waitpid(0, &status, WNOHANG)) > 0) {  //将while改为if
            if (WIFEXITED(status))
                printf("child %d exit %d
    ", pid, WEXITSTATUS(status));
            else if (WIFSIGNALED(status))
                printf("child %d cancel signal %d
    ", pid, WTERMSIG(status));
        }
    }

    此写法会导致子进程回收不完全,原因:在执行信号处理函数时,多个子进程同时死亡,产生多个SIGCHLD信号。但由于函数正在执行故屏蔽SIGCHLD,但执行完成后未决信号集中只记录一次SIGCHLD信号,故回收一次。子进程回收不完全。

  • 相关阅读:
    ElasticSearch简介(一)——基础
    .net core 3.0中动态卸载程序集
    修改VisualStudio的智能提示字体大小
    使用VisualStudio或VisualStudio Code作为代码比较工具
    编写一个爬虫类库——(二)准备
    编写一个爬虫类库——(一)想法
    linearLayout 和 relativeLayout的属性区别(转)
    如何在Root的手机上开启ViewServer,使得HierachyViewer能够连接(转)
    反编译APK文件的三种方法(转)
    Java中的锁(转)
  • 原文地址:https://www.cnblogs.com/lr1402585172/p/10563642.html
Copyright © 2011-2022 走看看