信號

一:信號:
日常生活中,我們會遇到很多信號,比如放學回家看到紅燈(信號),我們的”反應”是停下來.早上當鬧鈴響的時候我們大多數情況是選擇”關了”繼續睡,或者選擇”無視”.總是生活中有者各種各樣的形形色色的”信號”.
簡單的說所謂的信號是看到(識別),並且做出反應的行爲稱爲信號.

當然我們也可以通過指令查看信號
kill-l可以查看所有進程

這裏寫圖片描述
二:產生信號的條件:
1:用戶在終端按下按下某些鍵時, 驅動程序會把信號發給前臺進程如:Ctrl-C產生SIGINL信號
Ctrl-\產生SIGOUIT信號,我們看到結果有core dumped後面再分析.
這裏寫圖片描述
Ctrl-Z產生SIGTSTP信號
這裏寫圖片描述
2:硬件異常產生的信號,由硬件檢測然後通知內核,然後內核向當前進程發送適當的信息.常見的異常如除0,會產生SIGSEGV信號併發送給進程.

  1. ⼀一個進程調⽤用kill(2)函數可以發送信號給另⼀一個進程。 可以⽤用kill(1)命令發送信號 給某個進程,kill(1)命令也是調⽤用kill(2)函數實現的,如果不明確指定信號則發送
    SIGTERM信號,該信號的默認處理動作是終⽌該進程.

三:信號處理:
1:忽略:如鬧鐘信號產生,大多數情況是忽略的.
2:執行給信號的默認處理動作
3:提供一個函數要求內核在處理這個信號時,切換到用戶態執行這個處理函數,這正方式成爲(Catch)一個信號
signal函數
這裏寫圖片描述
signal函數的作用給某一進程某一特定信號註冊相應的處理函數,對默認處理動作進程修改,修改爲handler所指向的方式.
如:

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
void handler(int sig)
{
    printf("get a signal %d\n",sig);
}
int main()
{
  signal(2,handler);//產生信號
  while(1)
    {
        sleep(1);
        printf("hello i am a signal\n");
    }
    return 0;
}

這裏寫圖片描述
修改了2號信號(Ctrl-C)的默認處理方式,按Ctrl-C不會終止前臺進程.
四:產生信號
1:終端產生:
前面我們知道,SIGINT默認的處理動作是終止進程,SIGOUIT的默認處理動作是終止今後才能並且Core Dump.
首先解釋什麼是Core Dump.當一個進程要異常終止時,可以選擇把今後才能的用戶空間數內存數據全部保存到磁盤上,文件名通常是core,這個叫Core Dump.進程異常終止時因爲有Bug.比如非法內存的訪問導致段錯誤,事後可以用調試器檢查core文件以查清錯誤原因叫做事後調試,一個進程允許產生多大的core 文件取決於進程的Resourse Limit(信息保存在PCB中),在開發調試階段可以用ulimit命令改變這個限制允許產生core 文件.

首先ulimit命令改變shll進程的Resourse Limit,允許core 爲512k
$ulimit _c 512

這裏寫圖片描述
驗證:

#include<stdio.h>
#include<unistd.h>
int main()
{
printf("pid is %d\n",getpid());
    while(1);
    return 0;
}

按下Ctrl-Z就可以產生core dumped.
這裏寫圖片描述
ulimit命令改變了shll進程的Resouse Limit,mysig進程的PCB由shell進程複製而來,所以也具有和shell進程相同的Resouse Limit值沒這樣就可以Core Dump.
2:調用系統函數向進程發信號:
首先在後臺執行死循環程序,然後用kill命令給它發SIGSEGV信號

這裏寫圖片描述
4255 是mysig進程的id,之所以回車才顯示Segmentation fault,是因爲在4255進程終止之前已經回到shell提示符等待用戶輸入下一條命令,shell不希望segmentation fault信息和用戶的輸入交錯在一起,所以等用戶輸入命令之後才顯示.kill -11 4255,11是SIGSEGV的編號.

kill命令是調用kill函數可以給一個指定的進程發送指定的信號
raise函數可以給當前進程發送指定#include

#include<stdio.h>

int main()
{
  int count =0;
    alarm(1);
   while(1)
    {
      count++;
        printf("count is %d\n",count);
    }
    return 0;
}

這裏寫圖片描述
這個程序的作用就是1秒之內不停的數數,1秒鐘到了就會被SIGALRM信號終止.

總結:
信號產生的條件:
1:在終端按下某些鍵產生
2:硬件異常中斷產生
3:調用kill函數或者kill指令
4:alarm函數 和SIGALRM信號
處理信號的三種方式:
1:忽略此信號
2:執行默認處理動作
3:自定義(信號處理函數,信號捕捉catch)

發佈了113 篇原創文章 · 獲贊 62 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章