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

2017-04-18  本文已影响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函数,我们可以捕获一个信号

   /* 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**,执行系统默认动作

待续

... ...


参考

上一篇下一篇

猜你喜欢

热点阅读