linux中的兩個非常重要的訊號:SIGALRM訊號和SIGCHID訊號
在進行阻塞式系統呼叫時,為避免程式陷入無限期的等待,可以為這些阻塞式系統呼叫設定定時器。Linux提供了alarm系統呼叫和SIGALRM訊號實現這個功能。
要使用定時器,首先要安裝SIGALRM訊號。如果不安裝SIGALRM訊號,則程式收到SIGALRM訊號後,預設的動作就是終止當前程式。SIGALRM訊號安裝成功後,在什麼情況下程式會收到該訊號呢?這就要依賴於Linux提供的定時器功能。在Linux系統下,每個程式都有惟一的一個定時器,該定時器提供了以秒為單位的定時功能。在定時器設定的超時時間到達後,呼叫alarm的程式將收到SIGALRM訊號。alarm系統呼叫的原型為:
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
引數說明:
1)seconds:要設定的定時時間,以秒為單位。在alarm呼叫成功後開始計時,超過該時間將觸發SIGALRM訊號。
返回值:
返回當前程式以前設定的定時器剩餘秒數。
例8-10:程式設計利用SIGALRM訊號實現秒定時器。
程式碼如下:
#include <stdio.h>
#include <signal.h>
//全域性計數器變數
int Cnt=0;
//SIGALRM訊號處理函式
void CbSigAlrm(int signo)
{
//輸出定時提示資訊
printf(" seconds: %d",++Cnt);
printf("\r");
//重新啟動定時器,實現1秒定時
alarm(1);
}
void main()
{
//安裝SIGALRM訊號
if(signal(SIGALRM,CbSigAlrm)==SIG_ERR)
{
perror("signal");
return;
}
//關閉標準輸出的行快取模式
setbuf(stdout,NULL);
//啟動定時器
alarm(1);
//程式進入無限迴圈,只能手動終止
while(1)
{
//暫停,等待訊號
pause();
}
}
8.5.2 SIGCLD訊號
在Linux的多程式程式設計中,SIGCLD是一個非常重要的訊號。當一個子程式退出時,並不是立即釋放其佔用的資源,而是通知其父程式,由父程式進行後續的工作。在這一過程中,系統將依次產生下列事件。
1)向父程式傳送SIGCLD訊號,子程式進入zombie(殭屍)狀態。
2)父程式接收到SIGCLD訊號,進行處理。
如果在上述過程中父程式既沒有忽略SIGCLD訊號,也未捕獲該訊號進行處理,則子程式將進入殭屍狀態。殭屍狀態的程式不能被作業系統呼叫,也沒有任何可執行程式碼,它不過是佔用了程式列表中的一個位置而已。如果僅有幾個殭屍程式不會影響系統的執行,但是如果殭屍程式過多,則將會嚴重影響系統的執行。因此,在程式設計過程中應避免產生殭屍程式。有兩種基本的處理方法可以避免產生殭屍程式:一是父程式忽略SIGCLD訊號;二是父程式捕獲SIGCLD訊號,在訊號處理函式中獲取子程式的退出狀態。忽略訊號的方式比較簡單,只需要呼叫signal(SIGCLD,SIG_IGN)語句即可完成。如果要捕獲訊號並處理,那麼先要安裝SIGCLD訊號,然後在訊號處理函式中呼叫wait或者waitpid等函式獲取子程式的退出狀態。
例8-11:程式設計捕獲SIGCLD訊號,輸出各子程式的ID和退出狀態碼。
程式碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
//SIGCLD訊號處理函式
void CbSigCld(int signo)
{
//儲存退出程式的ID
int pid;
//儲存退出程式的退出狀態碼
int status;
//等待任何一個子程式退出
pid=waitpid(-1,&status,0);
//輸出退出的子程式ID和退出程式碼
printf("Child process %d exit with status %d\n",pid,status);
}
void main()
{
int i,pid;
//安裝SIGCLD訊號
if(signal(SIGCLD,CbSigCld)==SIG_ERR)
{
perror("signal");
return;
}
//迴圈建立子程式
for(i=0;i<5;i++)
{
pid=fork();
//如果是子程式
if(pid==0)
{
//退出子程式,退出狀態碼為0
exit(0);
}
//如果是父程式
else
{
sleep(1);
}
}
}
相關文章
- SIGALRM訊號和SIGCHID訊號GC
- Linux訊號機制與訊號處理Linux
- 細說 ReactiveCocoa 的冷訊號與熱訊號(三):怎麼處理冷訊號與熱訊號React
- Linux 未決訊號集與訊號遮蔽字Linux
- Linux中訊號量的實現Linux
- Linux中的System V訊號量Linux
- linux訊號的阻塞和未決Linux
- linux系統程式設計之訊號(一):中斷與訊號Linux程式設計
- 訊號課組(一) 訊號與系統 Part 0 MATLAB在訊號與系統中的使用Matlab
- Linux 下的程式間通訊:套接字和訊號Linux
- python中的訊號通訊 blinkerPython
- 音訊訊號表徵音訊
- 程序通訊-訊號
- Qt 5 中的訊號槽QT
- linux中的訊號處理與SROPLinux
- 細說 ReactiveCocoa 的冷訊號與熱訊號(1)React
- ReactiveCocoa 中 RACSignal 冷訊號和熱訊號底層實現分析React
- uc/os-iii學習筆記-資源管理(中斷、訊號、訊號量、互斥訊號量)筆記
- 語音訊號處理入門系列(2)——訊號處理中的幾個關鍵概念音訊
- django 訊號Django
- django的訊號量Django
- linux系統程式設計之訊號(五):訊號集操作函式,訊號阻塞與未決Linux程式設計函式
- linux 訊號機制Linux
- Linux 訊號量大全Linux
- linux訊號表(轉)Linux
- Linux下訊號燈的使用Linux
- 科學和工程中的訊號處理
- 處理python中的訊號Python
- Linux程式間通訊——使用訊號量Linux
- linux程式間通訊-----訊號總結Linux
- 基於EMD分解和訊號稀疏共振理論的軸承故障訊號分析
- 程式間通訊——POSIX 有名訊號量與無名訊號量
- linux 下的訊號量引數Linux
- linux中條件變數和訊號量的區別!Linux變數
- linux 訊號與處理Linux
- Linux訊號簡介(轉)Linux
- 分析外星訊號
- SIGCHLD訊號GC