zoukankan      html  css  js  c++  java
  • Linux 信号详解二(信号分类,信号处理,kill)

    信号分类
    信号分为可靠信号和不可靠信号
    不可靠信号的缺点 ①:处理完信号,需要重新再注册信号;②信号可能丢失。
    Linux已经对缺点①做了优化,现在的不可靠问题主要指的是信号可能丢失
    信号还可以分为实时信号和非实时信号--一般不可靠信号指的是前32种信号,这32种信号已经有了预定义值,每个信号有了确定的用途及含义,并且每种信号都有各自的缺省动作
    --可靠信号指的后32种信号
    --非实时信号都不支持排队,都是不可靠信号;实时信号都支持排队,都是可靠信号。
    信号处理
    进程对信号的三种响应
    1.忽略信号
    --不采取任何操作,有两个信号不能被忽略:SIGKILL(9号信号)和SIGSTOP。
    --如果进程可以忽略这两个信号,系统管理无法杀死,暂停进程,无法对系统进行管理。
    --SIGKILL(9号信号)和SIGSTOP信号是不能被捕获的
    2.捕获并处理信号
    --内核终端正在执行的代码,转去执行先前注册过的处理程序
    3.执行默认操作
    --默认操作通常是终止进程,这取决于被发送的信号
    信号发送
    发送信号的函数有kill和raise
    区别:kill既可以向自身发送信号,也可以向其他进程发送信号
    raise函数向进程自身发送信号
    int kill(oid_t pid,int sig)
    参数组合解释
     pid>0  将信号sig发给pid进程
     pid=0  将信号sig发给组进程
     pid=-1  将信号sig发送给所有进程,调用者进程有权限发送的每一个进程(除了1号进程之外,还有它自身)
     pid<-1  将信号sig发送给进程组pid(绝对值)的每一个进程
    //kill 函数
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <signal.h>
    
    void catch_signal(int sign)
    {
        switch(sign)
        {
        case SIGINT:
            printf("accept signal!
    ");
            break;
        default:
            break;
        }
    }
    
    int main(int arg,char *args[])
    {
        //注册信号
        if(signal(SIGINT,catch_signal)==SIG_ERR)
        {
            perror("signal error");
            return-1;
        }
        //注意:如果在fork之前安装信号,子进程会继承信号
        pid_t pid=0;
        pid=fork();
        if(pid==-1)
        {
            printf("fork() failed ! error message:%s
    ",strerror(errno));
            return -1;
        }
        if(pid==0)
        {
            printf("child runing!
    ");
            //kill(getppid(),SIGINT);//向父进程发送信号
            kill(0,SIGINT);//向进程组内所有进程发送信号(父子进程在同一个进程组中//getpgrp()获取进程组的pid,此处进程组ID就是父进程的pid
            /*killpg向一个进程组所有进程发送信号,第一个参数是进程组组长ID*/
            killpg(getpgrp(),SIGINT);
            exit(0);
        }
        printf("parent is runing!
    ");
    
        //等待子进程
        int status=0,ret=0;
        while(1)
        {
            ret=wait(&status);
            if(ret==-1)
            {
                if(errno==EINTR)
                {
                    continue;
                }
                break;
            }
        }
        printf("game over!
    ");
        return 0;
    }
  • 相关阅读:
    使用postman时请求参数中包含特殊字符问题,如加号传到后台变成空格
    okhttp3报错:java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
    Eclipse的知识积累
    partition 取数据中相同字段数据中取时间最大的一个值 并只保留一条
    理解Session缓存机制 操纵持久化对象
    Hibernate的检索策略
    LINQ介绍
    .Net 一对一的双向关联Map写法
    Hibernate多态查询
    NHibernate实战[转 2012 gogogo]
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/6075962.html
Copyright © 2011-2022 走看看