天天看點

C++信号處理

注冊處理信号

頭檔案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);
           

報錯:未知的信号或錯誤。

C++信号處理

系統給出的信号類型,在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;
}
           

輸出結果,列印連續。

C++信号處理

一個疑問

寫了個示例,第一次按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;
}
           

繼續閱讀