zoukankan      html  css  js  c++  java
  • SIGCHLD函数

    SIGCHLD的产生条件

    子进程终止时

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

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

    借助SIGCHLD信号回收子进程

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

    /***
    sigchild.c
    ***/
    #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) {
            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;
    }
    /***
    my_sigchild.c
    ***/
    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<errno.h>
    #include<sys/types.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()
    {
        pid_t pid;
        int i;
    
        for(i = 0; i < 10; i++)
        {
            if((pid = fork()) == 0)
            {
                break;
            }
            else if(pid < 0)
            {    
                sys_err("fork");
            }    
        }
    
        if(0 == pid)
        {
            int n = 1;
            while(n--)
            {
                printf("child ID %d
    ",getpid());
                sleep(1);
            }
            return i+1;
        }
        else if(pid > 0)
        {
            struct sigaction act;
            act.sa_handler = do_sig_child;
            sigemptyset(&act.sa_mask);
    
            while(1)
            {
                printf("Parent ID %d
    ",getpid());
                sleep(1);    
            }
    
        }
        return 0;
    }

    分析该例子。结合 17)SIGCHLD 信号默认动作,掌握父使用捕捉函数回收子进程的方式。              【sigchild.c】

           如果每创建一个子进程后不使用sleep可以吗?可不可以将程序中,捕捉函数内部的while替换为if?为什么?

          if ((pid = waitpid(0, &status, WNOHANG)) > 0) { ... }

          思考:信号不支持排队,当正在执行SIGCHLD捕捉函数时,再过来一个或多个SIGCHLD信号怎么办?

  • 相关阅读:
    开发用于异构环境的可生存云多机器人框架
    RVIZ实现模拟控制小车
    airsim 无法打开包括文件corecrt.h
    RoboWare Studio 安装
    Rosserial实现Windows-ROS交互操作
    nuix .pl文件运行
    OSError:[Errno 13] Permission denied:'my_library' 问题解决方法
    ros 运行rviz时出现 QXcbConnection: XCB error: 148 错误 解决方法
    在linux下一般用scp这个命令来通过ssh传输文件
    unix下命令窗分屏工具
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11336540.html
Copyright © 2011-2022 走看看