注冊處理信号
頭檔案signal.h。
param1:信号的類型。
param2:處理信号事件的回調函數。
void signal(int, void (*callback)(int));
注冊了某個信号後,當系統收到這個信号,就會調用回調函數。
這種注冊是一次性。意思是,系統調用了一次回調函數後,當這個信号再次觸發,系統将不會調用這個回調函數,而是使用預設的處理方法。
示例:
void callback(int tag){
cout << "recive signal : " << tag << endl;
}
int main()
{
signal(SIGINT, callback);
while (1){
Sleep(500);
raise(SIGINT);
}
return 0;
}
效果:控制台輸出一次後,程式自動關閉。
這種注冊是不可重複的。意思是,即使你連續重複注冊某個信号,實際效果與注冊一次相同。
示例:
void callback(int tag){
cout << "recive signal : " << tag << endl;
}
int main()
{
signal(SIGINT, callback);
signal(SIGINT, callback);
signal(SIGINT, callback);
while (1){
Sleep(500);
raise(SIGINT);
}
return 0;
}
效果:控制台輸出一次後,程式自動關閉。
主動發送信号
param1:信号的類型。
void raise(int)
發送的信号類型必須是系統給出的,不然,運作程式會報錯。
示例:
//main()中
raise(1);
報錯:未知的信号或錯誤。
系統給出的信号類型,在signal.h頭檔案中檢視。
類型 | 值 | 描述 |
---|---|---|
#define SIGINT | 2 | 中斷 |
#define SIGILL | 4 | 非法指令-無效函數鏡像 |
#define SIGFPE | 8 | 錯誤的算術運算,比如除以零或導緻溢出的操作 |
#define SIGSEGV | 11 | 非法通路記憶體 |
#define SIGTERM | 15 | 通過kill發送到本程序的終止信号 |
#define SIGBREAK | 21 | Ctrl-Break sequence |
#define SIGABRT | 22 | 程式的異常終止,如調用 abort。 |
#define SIGABRT_COMPAT | 6 | SIGABRT 相容其它平台, 類似于 SIGABRT |
連續收發同一信号示例
可以看到,發送周期為500毫秒,處理函數周期為1000毫秒。而控制台列印是連續的,是以,raise()是阻塞的。
void callback(int tag){
cout << "recive signal : " << tag << endl;
Sleep(1000);
signal(SIGINT, callback);
}
int main()
{
signal(SIGINT, callback);
while (1){
Sleep(500);
raise(SIGINT);
cout << "send signal : " << SIGINT << endl;
}
return 0;
}
輸出結果,列印連續。
一個疑問
寫了個示例,第一次按Ctrl+C,控制台沒輸出。通過打斷點,發現根本沒進回調函數。第二次按Ctrl+C,彈出警告視窗。
期望的效果是按下Ctrl+C,控制台有列印。難道這個示例在linux上才能有效果?
目前環境:win7 + VS2015。
代碼:
void callback(int tag){
cout << "recive signal : " << tag << endl;
}
int main()
{
signal(SIGINT, callback);
while (1){
Sleep(500);
}
return 0;
}