zoukankan      html  css  js  c++  java
  • Linux信号实践(1) --Linux信号编程概述

    中断

        中断是系统对于异步事件的响应, 进程执行代码的过程中可以随时被打断,然后去执行异常处理程序;

        计算机系统的中断场景:中断源发出中断信号 -> CPU判断中断是否屏蔽屏蔽以及保护现场 -> CPU(查询中断向量表, 找到中断服务程序的入口地址)执行中断处理程序 ->(处理完中断之后) ->恢复现场,继续执行原来的任务

     

    中断分类

    硬件中断(外部中断)

      外部中断是指由外部设备通过硬件请求的方式产生的中断,也称为硬件中断

    软件中断(内部中断)

      内部中断是由CPU运行程序错误或执行内部程序调用引起的一种中断,也称为软件中断(如:执行除0操作, 由用户空间陷入内核空间等)。

     

    信号

      信号是UNIX/Linux系统响应某些状况而产生的事件,进程在接收到信号时会采取相应的行动。信号一般是因为某些错误条件而产生的,比如内存段冲突、浮点处理器错误或者非法指令等;信号是在软件层次上对中断的一种模拟,所以通常把它称为是软中断;

     

    信号与中断的相似点:

    (1)采用了相同的异步通信方式

    (2)当检测出有信号或中断请求时,都暂停正在执行的程序而转去执行相应的处理程序;

    (3)都在处理完毕后返回到原来的断点

    (4)对信号或中断都可进行屏蔽

     

    信号与中断的区别:

    (1)中断有优先级,而信号没有优先级,所有的信号都是平等的;

    (2)信号处理程序是在用户态下运行的,而中断处理程序是在核心态下运行;

    (3)中断响应是及时的,而信号响应通常都有较大的时间延迟

     

    常用信号

    信号名称

    描述

    SIGABRT(6)

    进程停止运行 

    SIGALRM

    警告钟

    SIGFPE

    算述运算例外(如除0)

    SIGHUP

    系统挂断

    SIGILL

    非法指令

    SIGINT(2)

    终端中断  

    SIGKILL

    停止进程(此信号不能被忽略或捕获)

    SIGPIPE

    向没有读者的管道写入数据

    SIGSEGV

    无效内存段访问

    SIGQUIT

    终端退出   

    SIGTERM

    终止

    SIGUSR1

    用户定义信号1

    SIGUSR2

    用户定义信号2

    SIGCHLD

    子进程已经停止或退出

    SIGCONT

    如果被停止则继续执行

    SIGSTOP

    停止执行

    SIGTSTP

    终端停止信号

    SIGTOUT

    后台进程请求进行写操作

    SIGTTIN

    后台进程请求进行读操作

     

    进程对信号的响应 

    忽略信号  

      不采取任何操作、有两个信号不能被忽略:SIGKILL和SIGSTOP。

      [为什么进程不能忽略SIGKILL/SIGSTOP信号。(如果应用程序可以忽略这2个信号,系统管理无法杀死、暂停进程,无法对系统进行管理。)]

    捕获并处理信号   

      内核中断正在执行的代码,转去执行先前注册过的处理程序。

    执行默认操作   

      默认操作通常是终止进程,这取决于被发送的信号。

     

    信号的默认操作:通过 man 7 signal 查看

     

    信号安装-signal

    typedef void (*__sighandler_t) (int);
    #define SIG_ERR ((__sighandler_t) -1)
    #define SIG_DFL ((__sighandler_t) 0)
    #define SIG_IGN ((__sighandler_t) 1)
    __sighandler_t signal(int signum, __sighandler_t handler);

    参数

      signal是一个带signum和handler两个参数的函数,准备捕捉或屏蔽的信号由参数signum给出,接收到指定信号时将要调用的函数由handler给出

      handler这个函数必须有一个int类型的参数(即接收到的信号代码),它本身的类型是void, handler也可以是下面两个特殊值:

    SIG_IGN 屏蔽该信号

    SIG_DFL 恢复默认行为

    //示例1
    void handler(int sigNum)
    {
        cout << "recv a signal = " << sigNum << endl;
    }
    
    int main(int argc, char *argv[])
    {
        signal(SIGINT, handler);
        while (true)
            sleep(1);
    }

    RETURN VALUE

     signal() returns the previous value of the signal handler, or SIG_ERR on error.   

     In  the event of an error, errno is set to indicate the cause.

    int main(int argc, char *argv[])
    {
        sighandler_t oldHandler = signal(SIGINT, handler);
        if (oldHandler == SIG_ERR)
            err_exit("signal error");
    
        while (getchar() != '
    ')
            sleep(1);
    
        // 等价于 signal(SIGINT, SIG_DFL)
        if (signal(SIGINT, oldHandler) == SIG_ERR)
            err_exit("signal error");
    
        while (true)
            sleep(1);
    }
    //实例: 捕获所有信号, 并打印信号的信息
    int main()
    {
        for (int i = 1; i < NSIG; ++i)
        {
            if (signal(i, sigHandler) == SIG_ERR)
            {
                cerr << "signal " << i << ": " << strsignal(i) << " set error";
                cerr << ", errno desc: " << strerror(errno) << endl;
            }
        }
    
        while (true)
            pause();
    }
    
    void sigHandler(int signo)
    {
        cout << "catch a signal, signo = " << signo << ", desc: " << strsignal(signo) << endl;
    }


  • 相关阅读:
    c# EPPlus读取Excel里面的时间字段时,1900-01-01转成了1899-12-31
    c# MongoDB分页辅助类,支持多条件查询
    c#比较器辅助类
    mysql创建存储过程动态SQL语句
    MySQL数据库之DML(数据操作语言)
    MySQL数据库之DDL(数据定义语言)
    MySQL数据库的基本语法
    MySQL入门基础知识
    scala入门基础学习
    推荐算法杂点
  • 原文地址:https://www.cnblogs.com/itrena/p/5926971.html
Copyright © 2011-2022 走看看