• 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;
    }
  • 相关阅读:
    平方矩阵 II
    循环日程表
    十三号星期五
    寻找素数对
    全国省份数据表
    sqlserver--触发器(栗子)
    用户切换
    sqlserver学习--3(数据处理及比对)
    sqlserver学习--2(增删查改,CONVERT() 函数,sqlserver常用数据类型)
    sqlserver学习--1(登陆,时间函数,查看表结构,查看建表语句,IDENTITY() 函数,查询表名称,查询表结构)
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/6075962.html
Copyright © 2020-2023  润新知