zoukankan      html  css  js  c++  java
  • 信号的基本操作

    ctrl + c  --> 2)SIGINT 
    ctrl +   --> 3)SIGQUIT

    13)SIGPIPE     当管道读端关闭,再往管道写东西,会发出SIGPIPE信号 
    17)SIGCHLD   子进程退出会向父进程发出SIGCHLD信号,系统默认处理是忽略掉该信号

    #include<stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/wait.h>
    #include <signal.h>
    void handler(int num)
    {
        pid_t pid ;
        printf("sig_num: %d 
    ", num);
        pid = wait(NULL);
        printf("wait : %u 
    ", pid);
    }
    int main(int argc, char* argv[])
    {
        int fds[2];// fds[0] r  fds[1] w
        pipe(fds);
        char buf[1024];
        signal(SIGPIPE, handler);
        signal(SIGCHLD, handler);
        if(fork() == 0)
        {
            close(fds[1]);
            while(memset(buf, 0, 1024), read(fds[0], buf, 1024))
            {
                write(1, buf, strlen(buf));
            }
            printf("child over ! 
    ");
            exit(0);
        }
        if(fork() == 0)
        {
            exit(0);
        }
        if(fork() == 0)
        {
            exit(0);
        }
        close(fds[0]) ;
        while(memset(buf, 0, 1024), read(0, buf, 1024))
        {
            write(fds[1], buf, strlen(buf));
        }
        //while(1) ;
        return 0 ;
    }

    程序运行时,先是两个子进程先后退出,向父进程发送SIGCHLD 信号,接着执行handler函数,回收两个子进程资源。接着程序执行到父进程的while循环,由于read是阻塞函数,在我们没有按下enter或者ctrl+d之前,时间片会在第一个子进程和父进程之间来回切换。如果输入字符按enter,那么也就是父进程将其写入管道,子进程将其从管道中取出,并显示在屏幕上。

    如果按ctrl+d,则父进程退出while循环,并且退出程序。此时第一个子进程成为孤儿进程,被init收养,子进程退出时,会向init发送SIGCHLD 信号,由init回收资源。

    我们之所以将回收子进程资源的wait函数写在信号处理函数中,是因为wait是阻塞函数。如果父进程阻塞了就不能处理自己的工作了。

    之前我们已经提过,当子进程终止时,会给父进程发送SIGCHLD信号,虽然该信号的默认处理动作是忽略,但是父进程可以自定义SIGCHLD信号的处理函数,这样父进程只需专心处理自己的工作,不必关心子进程,当子进程终止时会通知父进程,父进程在信号处理函数中调用wait清理子进程资源即可。

    通常情况下服务器是永远不会退出的,因此我们可以在之前的程序中 return 0 前加个while(1),以此来模拟服务器。

    如果父进程先于子进程退出,则子进程成为孤儿进程,此时将自动被PID为1的进程(即init)接管。孤儿进程退出后,它的清理工作有祖先进程init自动处理。但在init进程清理子进程之前,它一直消耗系统的资源,所以要尽量避免。

    如果子进程先退出,系统不会自动清理掉子进程的环境,而必须由父进程调用wait或waitpid函数来完成清理工作,如果父进程不做清理工作,则已经退出的子进程将成为僵尸进程(defunct),在系统中如果存在的僵尸(zombie)进程过多,将会影响系统的性能,所以必须对僵尸进程进行处理。

  • 相关阅读:
    【移动安全高级篇】————2、浅谈Android软件安全自动化审计
    【移动安全实战篇】————1、Android手机下xx.apk JAVA破解之旅
    【移动安全高级篇】————1、Android沙盘原理与实现
    CLR
    反射
    泛型
    面试
    Sqlite
    粒子
    地图
  • 原文地址:https://www.cnblogs.com/hxjbc/p/3962165.html
Copyright © 2011-2022 走看看