美文网首页
从零开始UNIX环境高级编程(10):信号

从零开始UNIX环境高级编程(10):信号

作者: 伤口不该结疤 | 来源:发表于2017-04-18 20:40 被阅读161次

    0. 思维导图

    信号

    1. 信号概念


    1.1 信号的名字

    每个信号都有一个名字,这些名字以SIG开头。Linux将这些信号定义在/usr/include/bits/signum.h中。

    /* Signals.  */
    #define SIGIGHUP      1   /* Hangup (POSIX).  */
    #define SIGINT      2   /* Interrupt (ANSI).  */
    #define SIGQUIT     3   /* Quit (POSIX).  */
    #define SIGILL      4   /* Illegal instruction (ANSI).  */
    #define SIGTRAP     5   /* Trace trap (POSIX).  */
    #define SIGABRT     6   /* Abort (ANSI).  */
    #define SIGIOT      6   /* IOT trap (4.2 BSD).  */
    #define SIGBUS      7   /* BUS error (4.2 BSD).  */
    #define SIGFPE      8   /* Floating-point exception (ANSI).  */
    #define SIGKILL     9   /* Kill, unblockable (POSIX).  */
    ... ...
    ... ...
    #define SIGSYS      31  /* Bad system call.  */
    #define SIGUNUSED   31
    

    1.2 signal函数

    使用signal函数,我们可以捕获一个信号

    • 函数原型

      #include <signal.h>
      
      typedef void (*sighandler_t)(int);
      
      sighandler_t signal(int signum, sighandler_t handler);
      
    • 参数说明

    • signum:信号量,即信号的名字

    • 返回值
      returns the previous value of the signal handler, or SIG_ERR on error.

    • handler
      如果handler是一个函数地址,当收到signum信号时,则调用handler函数,该函数被称为信号处理函数
      如果handler的值是常量SIG_IGN,表示忽略此信号;后面会有一个示例
      如果handler的值是常量SIG_DFL表示按照系统默认动作执行
      SIG_IGN、SIG_DFL也定义在/usr/include/bits/signum.h中。

       /* Fake signal functions.  */
       #define SIG_ERR ((__sighandler_t) -1)       /* Error return.  */
       #define SIG_DFL ((__sighandler_t) 0)        /* Default action.  */
       #define SIG_IGN ((__sighandler_t) 1)        /* Ignore signal.  */
    

    1.3 产生信号的条件

    产生信号的条件

    1.4 处理信号的方式

    处理信号的方式一共有3种,分别是:捕捉信号忽略此信号执行系统默认动作

    1. 捕捉信号

    使用signal函数可以捕获信号

    • 示例代码

    当捕获当SIGINT信号时,就调用sig_int函数,打印received SIGINT

    #include "apue.h"
    
    void sig_int()
    {
        printf("received SIGINT\n");
        return;
    }
    
    int main(int argc, char const *argv[])
    {
        signal(SIGINT, sig_int);
        for (; ;)
            sleep(1);
        return 0;
    }
    
    • 输出结果
    捕捉信号
    2. 忽略此信号

    将signal函数的handler参数赋值为SIG_IGN,就可以实现忽略此信号的功能

    • 示例代码

    当用户输出ctrl+c时,产生的SIGINT信号会被忽略

    #include "apue.h"
    
    int main(int argc, char const *argv[])
    {
        signal(SIGINT, SIG_IGN);
        for (; ;)
            sleep(1);
        return 0;
    }
    
    • 输出结果
    signal
    3. 执行系统默认动作

    如果没对信号进行捕获或者忽略,那么在收到信号时,进行将执行系统默认动作。使用man kill可以查看每个信号对应的系统执行默认动作。例如,SIGINT的默认Action为exit,即如果进程收到该信号,默认执行进程退出。

    man kill

    除了exit,系统的支持的action还有ignore(忽略)stop(停止)core。其中core指的是进程收到信号后会产生一个Core Dump File

    Core Dump File是否生成由Core文件大小决定,Linux中默认的Core文件大小设置为零,也就是不生成Core Dump File。想要生成Core Dump File,需要通过命令 ulimit -c unlimited 来设置Core文件大小为无限制

    root@ubuntu:/home/ckt/work/unix/code/chapter10# ulimit -c unlimited
    

    通过命令**echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern **可以设置Core Dump File的命令规则

    root@ubuntu:/home/ckt/work/unix/code/chapter10# echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern
    

    运行上面例子中的signal程序,让它在后台运行,使用kill命令发送SIGSEGV信号给该进程,由于SIGSEGV的默认action为core,该进程在收到SIGSEGV信号后会生成一个Core Dump File

    root@ubuntu:/home/ckt/work/unix/code/chapter10# ./signal &
    [1] 16613
    root@ubuntu:/home/ckt/work/unix/code/chapter10# jobs
    [1]+  Running                 ./signal &
    root@ubuntu:/home/ckt/work/unix/code/chapter10# kill -11 %1
    root@ubuntu:/home/ckt/work/unix/code/chapter10# 
    [1]+  Segmentation fault      (core dumped) ./signal
    root@ubuntu:/home/ckt/work/unix/code/chapter10# ls -l | grep core
    -rw------- 1 root root 253952 Apr 18 01:53 core-signal-16613-1492505601
    

    下面以一段代码演示由于进程没有捕获SIGINT,再收到该信号后,进程会执行退出

    • 示例代码
    #include "apue.h"
    
    int main(int argc, char const *argv[])
    {
        for (; ;)
            sleep(1);
        return 0;
    }
    
    • 输出结果
    没有捕获**SIGINT**,执行系统默认动作

    待续

    ... ...


    参考

    相关文章

      网友评论

          本文标题:从零开始UNIX环境高级编程(10):信号

          本文链接:https://www.haomeiwen.com/subject/yugzattx.html