[筆記]Windows的訊號機制(Signals)

來源:互聯網
上載者:User

Windows下的signal,Piaoger一直沒有機會用到,今天既然在一個Console程式中碰到了,就很有必要把玩把玩,廣搜天下,並做些筆記:


>> Windows下的訊號(Signal)

訊號是進程在運行過程中,由自身產生或由進程外部發過來的訊息。

訊號是硬體中斷的軟體類比(非強制中斷)。每個訊號用一個整型常量宏表示,以SIG開頭,比如SIGCHLD、SIGINT等,它們在系統標頭檔中<signal.h>定義。

這玩意兒據說Linux也有,但相當不一樣,有時間可以zhuangB看看。

>> 訊號的來源

訊號的產生來自核心,讓核心產生訊號的請求來自3個地方:使用者、核心護著進程。

++ 使用者:使用者能夠通過輸入CTRL+c、Ctrl+,或者是終端驅動程式分配給訊號控制字元的其他任何鍵來請求核心產生訊號;

++ 核心:當進程執行出錯時,核心會給進程發送一個訊號,例如非法段存取(記憶體訪問違規)、浮點數溢出等

++ 進程:一個進程可以通過系統調用kill給另一個進程發送訊號,一個進程可以通過訊號和另外一個進程進行通訊。

由進程的某個操作產生的訊號稱為同步訊號(synchronous signals),例如除0;由使用者擊鍵之類的進程外來事件產生的訊號叫做非同步訊號。(asynchronous signals)。


>> 訊號的處理

進程接收到訊號以後,可以有如下3種選擇進行處理:

++ 接收預設處理:接收預設處理的進程通常會導致進程本身消亡。例如串連到終端的進程,使用者按下CTRL+c,將導致核心向進程發送一個SIGINT的訊號,進程如果不對該訊號做特殊的處理,系統將採用預設的方式處理該訊號,即終止進程的執行;

++ 忽略訊號:進程可以通過代碼,顯示地忽略某個訊號的處理,例如:signal(SIGINT,SIGDEF);但是某些訊號是不能被忽略的,

++ 捕捉訊號並處理:進程可以事先註冊訊號處理函數,當接收到訊號時,由訊號處理函數自動貼齊並且處理訊號。

有兩個訊號既不能被忽略也不能被捕捉,它們是SIGKILL和SIGSTOP。即進程接收到這兩個訊號後,只能接受系統的預設處理,即終止線程。


>> Windows Signal Types

#include <signal.h>

// Ctrl-C handler
static int b_ctrl_c = 0;
static int b_exit_on_ctrl_c = 0;

// Signal types
#define SIGINT 2 // interrupt(Ctrl+C中斷)
#define SIGILL 4 // illegal instruction - invalid function image(非法指令)
#define SIGFPE 8 // floating point exception(浮點異常)
#define SIGSEGV 11 // segment violation(段錯誤)
#define SIGTERM 5 // Software termination signal from kill(Kill發出的軟體終止)
#define SIGBREAK 21 //Ctrl-Break sequence(Ctrl+Break中斷)
#define SIGABRT 22 // abnormal termination triggered by abort call(Abort)


 >> Windows Signal Handling

訊號處理函數用於設定訊號處理的Handler。

 

#include <signal.h>

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

signal用於設定訊號的捕捉函數。signal如果調用成功,返回以前該訊號的處理函數的地址,否則返回 SIG_ERR。

++ signum:要捕捉的訊號,

++ handler: 函數指標,表示要對該訊號進行捕捉的函數,該參數也可以是SIG_DEF(表示交由系統預設處理,無需理會)或SIG_IGN(表示忽略掉該訊號而不做任何處理)。

sighandler_t是訊號捕捉函數,由signal函數註冊,註冊以後,在整個進程運行過程中均有效,並且對不同的訊號可以註冊同一個訊號捕捉函數。唯一的傳入參數表示訊號值。


>> MSDN上的小例子
這個小例子示範了如何處理Abort訊號。

// Use signal to attach a signal handler to the abort routine
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <tchar.h>

void SignalHandler(int signal)
{
printf("Application aborting...\n");
}

int main()
{
typedef void (*SignalHandlerPointer)(int);

SignalHandlerPointer previousHandler;
previousHandler = signal(SIGABRT, SignalHandler);

abort();
}

>> More

據說還有更NB與可靠的sigaction訊號處理機制,既然是初來乍到,就留到以後來瞭解吧。

- Piaoger


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.