信號的捕獲和處理

      信號(signal)是在特定事件發生時由操作系統向進程發送的消息。它一種軟件中斷,是進程間唯一的異步通信方式。

      信號有很多,常見的有:

  • SIGINT:在鍵盤按下<Ctrl+C>組合鍵後產生,默認動作爲終止進程
  • SIGQUIT:在鍵盤按下<Ctrl+\>組合鍵後產生,默認動作爲終止進程
  • SIGKILL:無條件終止進程。本信號不能被忽略、處理和阻塞。默認動作爲終止進程。它向系統管理員提供了一種可以殺死任何進程的方法
  • SIGALRM:定時器超時,超時的時間由系統調用alarm設置。默認動作爲終止進程
  • SIGCHLD:子進程結束時,父進程會收到這個信號。默認動作爲忽略該信號


      信號的捕捉和處理


      信號的捕捉和處理由以下2個函數來完成,其中第一個函數也是由第二個函數實現的:

#include <signal.h>
sighandler_t signal(int signum, sighandler_t handler);
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

      參數signum指定信號的種類,比如SIGINT、SIGKILL等。

      參數handler是一個函數指針,指定捕捉到該信號後的處理函數。

      signal函數執行成功時返回信號處理函數指針,發生錯誤時返回SIG_ERR。

      sigaction函數類似於signal函數,而且它完全可以替代後者,也更穩定。之所以穩定,是signal函數在UNIX系列的不同操作系統中可能存在區別,但sigaction函數完全相同。實際上現在很少用signal函數來編寫程序,它只是爲了保持對舊程序的兼容。

1. signal()函數

#include <stdio.h>
#include <signal.h>

/*信號處理函數*/
void handler_sigint(int signo)
{
	printf("recv SIGINT\n");
}

int main()
{
	/*安裝信號處理函數*/
	signal(SIGINT, handler_sigint);
	
	while(1)
		;

	return 0;
}

      程序使用signal()安裝SIGINT的處理函數handler_sigint,然後進入無限循環。當接收到SIGINT信號時,程序自動跳轉到信號處理函數處執行,打印出提示信息。然後返回主函數繼續無限循環。執行結果如下:



2. sigaction()函數

      sigaction函數中用到了一個結構體sigaction作爲參數。此結構體中的字段常用的有2個,sa_handler用來指定信號發生後的處理函數,sa_flags用來進行一些設定。

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

int temp = 0;

/*信號處理函數*/
void handler_sigint(int signo)
{
	printf("recv SIGINT\n");
	sleep(5);
	temp += 1;
	printf("the value of temp is: %d\n", temp);
	printf("in handler_sigint, after sleep\n");
}

int main()
{
	struct sigaction act;
	
	/*賦值act結構*/
	act.sa_handler = handler_sigint;
	act.sa_flags = SA_NOMASK;      //此設置意味着,對於可靠信號,發生了多少次,就調用信號處理函數多少次,即信號不會丟失
	/*安裝信號處理函數*/
	sigaction(SIGINT, &act, NULL);
	
	while(1)
		;

	return 0;
}

      運行上述程序後,在鍵盤上快速按下5次<Ctrl+C>組合鍵,屏幕上會連續打印出5行提示消息。在休眠5秒後,再將臨時變量temp的值依次打印出來。這是由於設定了sa_flags的值爲SA_NOMASK,因此程序能夠反覆響應信號SIGINT,程序從sleep()處嵌套調用信號處理函數handler_sigint,多次打印出“recv SIGINT”。睡眠5秒後,將temp的值打印出來並返回到本次信號處理程序的跳入點sleep()處,最後返回到主函數。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章