從零開始UNIX環(huán)境高級(jí)編程(10):信號(hào)

0. 思維導(dǎo)圖

信號(hào)

1. 信號(hào)概念


1.1 信號(hào)的名字

每個(gè)信號(hào)都有一個(gè)名字,這些名字以SIG開頭。Linux將這些信號(hào)定義在/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函數(shù)

使用signal函數(shù),我們可以捕獲一個(gè)信號(hào)

  • 函數(shù)原型

    #include <signal.h>
    
    typedef void (*sighandler_t)(int);
    
    sighandler_t signal(int signum, sighandler_t handler);
    
  • 參數(shù)說明

  • signum:信號(hào)量,即信號(hào)的名字

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

  • handler
    如果handler是一個(gè)函數(shù)地址,當(dāng)收到signum信號(hào)時(shí),則調(diào)用handler函數(shù),該函數(shù)被稱為信號(hào)處理函數(shù);
    如果handler的值是常量SIG_IGN,表示忽略此信號(hào);后面會(huì)有一個(gè)示例
    如果handler的值是常量SIG_DFL表示按照系統(tǒng)默認(rèn)動(dòng)作執(zhí)行。
    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 產(chǎn)生信號(hào)的條件

產(chǎn)生信號(hào)的條件

1.4 處理信號(hào)的方式

處理信號(hào)的方式一共有3種,分別是:捕捉信號(hào)忽略此信號(hào)執(zhí)行系統(tǒng)默認(rèn)動(dòng)作

1. 捕捉信號(hào)

使用signal函數(shù)可以捕獲信號(hào)

  • 示例代碼

當(dāng)捕獲當(dāng)SIGINT信號(hào)時(shí),就調(diào)用sig_int函數(shù),打印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;
}
  • 輸出結(jié)果
捕捉信號(hào)

2. 忽略此信號(hào)

將signal函數(shù)的handler參數(shù)賦值為SIG_IGN,就可以實(shí)現(xiàn)忽略此信號(hào)的功能

  • 示例代碼

當(dāng)用戶輸出ctrl+c時(shí),產(chǎn)生的SIGINT信號(hào)會(huì)被忽略

#include "apue.h"

int main(int argc, char const *argv[])
{
    signal(SIGINT, SIG_IGN);
    for (; ;)
        sleep(1);
    return 0;
}
  • 輸出結(jié)果
signal

3. 執(zhí)行系統(tǒng)默認(rèn)動(dòng)作

如果沒對(duì)信號(hào)進(jìn)行捕獲或者忽略,那么在收到信號(hào)時(shí),進(jìn)行將執(zhí)行系統(tǒng)默認(rèn)動(dòng)作。使用man kill可以查看每個(gè)信號(hào)對(duì)應(yīng)的系統(tǒng)執(zhí)行默認(rèn)動(dòng)作。例如,SIGINT的默認(rèn)Action為exit,即如果進(jìn)程收到該信號(hào),默認(rèn)執(zhí)行進(jìn)程退出。

man kill

除了exit,系統(tǒng)的支持的action還有ignore(忽略)、stop(停止)core。其中core指的是進(jìn)程收到信號(hào)后會(huì)產(chǎn)生一個(gè)Core Dump File。

Core Dump File是否生成由Core文件大小決定,Linux中默認(rèn)的Core文件大小設(shè)置為零,也就是不生成Core Dump File。想要生成Core Dump File,需要通過命令 ulimit -c unlimited 來設(shè)置Core文件大小為無限制。

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

通過命令**echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern **可以設(shè)置Core Dump File的命令規(guī)則

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

運(yùn)行上面例子中的signal程序,讓它在后臺(tái)運(yùn)行,使用kill命令發(fā)送SIGSEGV信號(hào)給該進(jìn)程,由于SIGSEGV的默認(rèn)action為core,該進(jìn)程在收到SIGSEGV信號(hào)后會(huì)生成一個(gè)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

下面以一段代碼演示由于進(jìn)程沒有捕獲SIGINT,再收到該信號(hào)后,進(jìn)程會(huì)執(zhí)行退出

  • 示例代碼
#include "apue.h"

int main(int argc, char const *argv[])
{
    for (; ;)
        sleep(1);
    return 0;
}
  • 輸出結(jié)果
沒有捕獲**SIGINT**,執(zhí)行系統(tǒng)默認(rèn)動(dòng)作

待續(xù)

... ...


參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 什么是中斷? 在計(jì)算機(jī)科學(xué)中,中斷是指由于接收到外圍硬件(相對(duì)于CPU與內(nèi)存而言)的異步信號(hào)或者來自軟件的同步信號(hào)...
    hailiu13閱讀 1,251評(píng)論 0 1
  • 轉(zhuǎn)自:http://www.dbafree.net/?p=870 我們可以使用kill -l查看所有的信號(hào)量解釋,...
    AndreaArlex閱讀 6,314評(píng)論 0 4
  • 對(duì)于 Linux來說,實(shí)際信號(hào)是軟中斷,許多重要的程序都需要處理信號(hào)。信號(hào),為 Linux 提供了一種處理異步事件...
    故事狗閱讀 86,260評(píng)論 2 63
  • Chris Richardson 微服務(wù)系列翻譯全7篇鏈接: 微服務(wù)介紹 構(gòu)建微服務(wù)之使用API網(wǎng)關(guān) 構(gòu)建微服務(wù)之...
    butterfly100閱讀 776評(píng)論 0 2
  • 最近有客戶在后臺(tái)咨詢說家中正在裝修,超五類網(wǎng)線已經(jīng)鋪放過了,現(xiàn)在又想實(shí)現(xiàn)千兆網(wǎng)絡(luò)。那么超五類網(wǎng)線可以到達(dá)千兆的速度...
    enrilink閱讀 21,396評(píng)論 0 0

友情鏈接更多精彩內(nèi)容