4412開發板運行之進程通訊專題 | 信號通訊

在iTOP4412開發板運行中,當咱們在win上遇到一個沒有辦法正常關閉的軟件的時候,咱們能夠打開任務管理器,強制結束這個進程,同理。在linux上也有相似的功能,好比從終端敲入ctrl+c組合鍵來產生一個信號,當運行中的進程捕捉到這個信號後就會作出反應。linux

咱們在win上可使用快捷鍵進入任務管理器,那麼linux中會在哪些狀況下會產生信號呢?函數

那麼linux有多少種信號呢,咱們能夠經過命令kill命令來查看,以下圖:blog

 經過上面的截圖咱們能夠發現,一共有64種信號,每一個信號都是以sig開頭,信號的名稱是在signal.h中定義的。進程

本次文章主要涉及到三個內容,一,信號的發送,二,信號的接收,三,信號的處理。開發

第一部分:信號的發送原型

咱們經過一個小例子來認識下信號的發送:io

這個程序主要用到了kill函數, 由於用戶空間是不具有發送信號的能力的,只有內核才能夠發信號,內核有那麼多信號,咱們要發哪一個信號,而且發給誰呢?那麼咱們就須要先告訴內核進程PID,信號ID是多少,kill函數就幫咱們解決了這個問題,函數原型:編譯

因此在上面的例子中,咱們就能夠經過kill函數來向內核發送一次產生信號的請求。 軟件

咱們再來看一個和kill函數很像的函數,raise函數 ,與kill函數不一樣的是,它沒有第一個參數,他不知道要發信號給誰,因此他只能發信號給本身。咱們來看下這個例子:終端

編譯並運行:

函數原型:

從kill和raise的函數原型上看,raise沒有pid這個參數,因此raise是能夠經過kill來實現的。等價於:

還有一個須要瞭解的函數alarm函數,與raise函數不一樣的是,他只能發alarm信號,而且能夠定時發送信號,而raise是馬上讓內核發信號。因此這個函數的參數沒有pid號,也沒有信號ID,只有一個延遲的秒數。須要注意的是,一個進程只能有一個alarm時間,函數原型:

第一部分信號發送總結:

用戶空間不能發送信號,是經過系統調用函數告訴內核發什麼信號,發給誰,讓內核來發送的,只有內核才能夠發信號。可使用kill,raise,alarm函數來讓內核發送信號。

第二部分信號接收

咱們可使用pause來接收信號,pause函數使該進程暫停讓出CPU。咱們來看下下面這個例子,當咱們在鍵盤上按下ctrl+c的時候,程序收到SIGINT信號會被喚醒,而後執行fun函數,處理完以後再返回繼續運行該程序,不按則只打印process start(進入睡眠狀態)。

 

函數原型:

第三部分信號處理

信號的處理有三種方式,分別爲:1,忽略,就是收到信號後,什麼也不作,不處理。2,按照默認的方式處理。3,捕獲並處理,捕獲到信號後,執行咱們本身想執行的代碼。咱們先來看下signal函數:

第一種處理方式,忽略:

咱們來看下這個例子。

編譯並運行,由於咱們使用的參數爲SIG_IGN,因此咱們按下ctrl+c的時候並不能中斷程序運行.

第二種處理方式,按照默認的方式處理,咱們把上個例子中的參數改爲SIG_DFL,以下:

編譯並運行,當咱們按下ctrl+c的時候,會中斷咱們程序。

第三種處理方式,執行咱們本身的代碼:

當咱們按下ctrl+c的時候,會進去到fun函數。

三個部分總結:

1,咱們可使用kill命令來查看有多少個信號,在這麼多信號中,咱們要格外記住如下幾個:

 2,用戶空間不能發送信號,信號的產生來自內核,讓內核產生信號的方式有:經過鍵盤輸入ctrl+c等。當程序運行出錯時,內核會給進程發送一個信號,如浮點溢出等,還有就是一個程序能夠經過調用函數來給另一個進程發信號,如kill。

3,進程收到信號後,能夠忽略,或者按照默認的方式處理,或者按照本身的處理函數來處理,signale是永久註冊的,每次都有效,若是不想的話這樣可使用sigaction。

相關文章
相關標籤/搜索