1. 程式人生 > >Linux程序通訊-訊號通訊

Linux程序通訊-訊號通訊

訊號(signal)機制是unix系統中最為古老的程序間通訊機制,很多條件可以產生一個訊號:
1、當用戶按某些按鍵時,產生訊號
2、硬體異常產生訊號:除數為0、無效的儲存訪問等等。這些情況通常由硬體檢測到,將其通知核心,然後核心產生適當的訊號通知程序,例如:核心對正訪問一個無效儲存區的程序產生一個SIGSEGV訊號。
3、程序用kill函式將訊號傳送給另一個程序
4、使用者可用kill命令將訊號傳送給其他程序

下面是常見的幾種訊號型別:

  • SIGHUP:從終端上發出的結束訊號
  • SIGINT:來自鍵盤的中斷訊號(crtl-c)
  • SIGKILL:該訊號結束接收訊號的程序
  • SIGTERM:kill命令發出的訊號
  • SIGCHLD:標識子程序停止或結束的訊號
  • SIGSTOP:來自鍵盤(ctrl-z)或除錯程式的停止執行訊號

訊號處理:
當某訊號出現時,將按照下列三種方式中的一種進行處理:
1、忽略此訊號
大多數訊號都按照這種方式進行處理,但有兩種訊號決不能被忽略。SIGKILL和SIGSTOP。這兩種訊號不能被忽略的原因是:他們想超級使用者提供了一種終止或停止程序的方法。
2、執行使用者希望的動作
通知核心在某種訊號發生時,呼叫一個使用者函式。在使用者函式中,執行使用者希望的處理。
3、執行系統預設動作
對大多數訊號的系統預設動作是終止該程序。

訊號傳送
傳送訊號的主要函式有kill和raise。
區別:
kill既可以向自身傳送訊號,也可以像其他程序傳送訊號。與kill函式不同的是,raise函式是向程序自身傳送訊號。
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid,int signo)
int raise(int signo)

kill的pid引數有四種不同的情況:
1、pid>0 :將訊號傳送給程序ID為pid的程序
2、pid==0:將訊號傳送給同組的程序
3、pid<0:將訊號傳送給其他程序組ID等於pid絕對值的程序
4、pid=-1:將訊號傳送給所有的程序

pause函式使呼叫程序掛起直至捕捉到一個訊號。
#include<unistd.h>
int pause(void)
只有執行一個訊號處理函式後,掛起才結束。

訊號處理

  • 當系統捕捉到某個訊號時,可以忽略該訊號或是使用指定的處理函式來處理該訊號,或者使用系統預設的方式。
  • 訊號處理的主要方法有兩種,一種是使用簡單的signal函式,另一種是使用訊號集函式組。

#include<signal.h>
void(*signal(intsigno,void(*func)(int)))(int)(函式指標)
不太懂可以參考這篇文章:http://nevel.cnblogs.com/p/6370264.html
Func可能的值是:
1、SIG_IGN:忽略此訊號
2、SIG_DFL:按系統預設方式處理
3、訊號處理函式名:使用該函式處理

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

void my_func(int sign_no)
{
	if(sign_no==SIGINT)
		printf("I have get SIGINT\n");
	else if(sign_no==SIGQUIT)
		printf("I have get SIGQUIT\n");
}
int main()
{
	printf("Waiting for signal SIGINT or SIGQUIT \n ");
	
	/*註冊訊號處理函式*/
	signal(SIGINT, my_func);
	signal(SIGQUIT, my_func);
	
	pause();
	exit(0);
}


在linux上有:
先開一個終端執行程式碼:
在這裡插入圖片描述
開另一個終端傳送訊號:
使用ps aux檢視程序號
在這裡插入圖片描述
signal已經在運行了
使用kill命令傳送 kill -s SIGINT +pid
在這裡插入圖片描述