linux系統中的信號相關知識點概述記錄

1、什麼是信號

1.1、信號是內容受限的一種異步通信機制

(1)信號的目的:用來通信

(2)信號是異步的(對比硬件中斷)

(3)信號本質上是int型數字編號(事先定義好的)

 

1.2、信號由誰發出

(1)用戶在終端按下按鍵

(2)硬件異常後由操作系統內核發出信號

(3)用戶使用kill命令向其他進程發出信號

(4)某種軟件條件滿足後也會發出信號,如alarm鬧鐘時間到會產生SIGALRM信號,向一個讀端已經關閉的管道write時會產生SIGPIPE信號。

 

1.3、信號處理方式

(1)忽略信號

(2)捕獲信號(信號綁定了一個函數)

(3)默認處理(當前進程沒有明顯的管這個信號,默認:忽略或終止進程)

 

 

 

2、常見信號介紹

(1)SIGINT                                 2                  Ctrl+C時OS發送給前臺進程組中每個進程

(2)SIGABRT                             6                  調用abort函數,進程異常終止

(3)SIGPOLL SIGIO                   8                  指示一個異步IO事件,在高級IO中體積

(4)SIGKILL                                9                  殺死進程的終極方法

(5)SIGSEGV                             11                 無效存儲訪問時OS發出該信號

(6)SIGPIPE                               13                 涉及管道和socket

(7)SIGALRM                              14                 涉及alarm函數的實現

(8)SIGTERM                              15                 kill命令發送的OS默認終止信號

(9)SIGCHLD                               17                子進程終止或停止時OS向其父進程發送此信號

(10)

SIGUSR1                                         10                 用戶自定義信號,作用和意義由應用自己定義

SIGUSR2                                         12

 

 

 

3、進程對信號的處理

3.1、signal函數

3.2、用signal函數處理SIGINT信號

(1)默認處理

(2)忽略處理

(3)捕獲處理

細節:

(1)signal函數綁定一個捕獲函數後,信號發生後會自動執行綁定的捕獲函數,並且把信號編號作爲傳參傳給捕獲函數。

(2)signal的返回值在出錯時爲SIG_ERR,綁定成功時返回舊的捕獲函數。

 

3.3、signal函數的優點和缺點

(1)優點:簡單好用,捕獲信號常用

(2)缺點:無法簡單直接得知之前設置的對信號的處理方法

 

3.4、sigaction函數介紹

(1)2個都是API,但是sigaction比signal更具有可移植性

(2)用法關鍵是2個sigaction指針

編程實例:

/*
*功能描述:
*將SIGINT 2	Ctrl+C時OS發送給前臺進程組中每個進程,即“CTRL + C”功能重綁定到捕獲函數func
*重綁定信號捕獲函數func之後,
*當在終端按下“CTRL + C”時,不再執行OS發送給前臺進程組中每個進程,即終止當前進程的功能
*而是去執行用戶自定義的信號捕獲函數func中的內容
*要想結束當前進程,在linux系統中,先使用“ps -ajx”查看當前進程的進程號,記爲xxx
*最後,用“kill -9 xxx”結束該進程。
*/


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

// typedef void (*sighandler_t)(int);
	
void func(int sig)
{
	if(SIGINT != sig)
	{
		perror("signal");
		return;
	}
	printf("func for signal: %d.\n", sig);
}


int main(void)
{
	// sighandler_t ret = (sighandler_t)-2;

	signal(SIGINT, func);
	//signal(SIGINT, SIG_DFL);	//指定信號SIGINT爲默認處理
	//signal(SIGINT, SIG_IGN);	//指定信號SIG_IGN爲忽略處理
		
	printf("before while(1)\n");
	
	while(1);
	
	printf("after while(1)\n");
		
	return 0;
}

 

 

 

4、alarm和pause函數

4.1、alarm函數

(1)內核以API形式提供的鬧鐘

 

4.2、pause函數

(1)內核掛起

pause函數的作用就是讓當前進程暫停運行,交出CPU給其它進程去執行。噹噹前進程進入pause狀態後,當前進程會表現爲“卡住、阻塞住”,要退出pause狀態,當前進程需要被信號喚醒。

 

編程實例:

/*
*功能描述:測試sigaction()、alarm()函數和pause()函數的使用
*1、使用sigaction()函數綁定一個捕獲函數func
*2、使用alarm()函數設置一個發送信號的鬧鐘,發送的信號爲SIGALRM			
*3、使用pause()掛起當前進程,當前進程等待alarm信號發生被喚醒執行func函數
*/

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

void func(int sig)
{
	if(SIGALRM == sig)
	{
		printf("alarm happened!\n");
	}
}

int main(void)
{
	unsigned int ret = 0;
	struct sigaction act = {0};
	act.sa_handler = func;
	sigaction(SIGALRM, &act, NULL);
	//signal(SIGALRM, func);
	
	ret = alarm(5);	//5s  設置一個發送信號的鬧鐘
	printf("1st,ret = %d.\n", ret);
	sleep(3);
	
	ret = alarm(5);	//5s  
	printf("2st,ret = %d.\n", ret);
	sleep(1);
	
	ret = alarm(5);	//5s  
	printf("3st,ret = %d.\n", ret);
	pause();  // 內核掛起當前進程  當前進程等待alarm信號發生被喚醒

	return 0;
}

 

 

4.3、使用alarm和pause來模擬sleep

編程實例:

/*
*功能描述:使用alarm和pause來模擬sleep
*1、使用sigaction()綁定信號捕獲函數func  
*2、使用alarm()函數設置一個發送信號的鬧鐘,發送的信號爲SIGALRM			
*3、使用pause()掛起當前進程,當前進程等待alarm信號發生被喚醒執行func函數
*/

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

void func();	
void mysleep(unsigned int seconds);

int main(void)
{
	printf("before mysleep.\n");
	
	mysleep(3);
	
	printf("after mysleep.\n");
	
	return 0;
}

void func(){}	

void mysleep(unsigned int seconds)
{
	struct sigaction act = {0};
	act.sa_handler = func;
	sigaction(SIGALRM, &act, NULL);		//綁定信號捕獲函數func  
	
	alarm(seconds);		//設置alarm函數執行seconds秒
	
	//進程掛起,
	//等待alarm函數執行完畢,產生信號SIGALRM喚醒當前進程,執行捕獲信號發生func
	pause(); 
}

 

 

 

 

 

注:筆記整理記錄於——《朱老師物聯網大講堂》—3.5linux中的信號

https://edu.csdn.net/course/play/2405/37602

 

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