日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 信号处理函数详解

發(fā)布時間:2023/12/20 linux 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 信号处理函数详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:http://blog.csdn.NET/sddzycnqjn/article/details/7285760


1. 信號概念?
信號是進程在運行過程中,由自身產生或由進程外部發(fā)過來的消息(事件)。信號是硬件中斷的軟件模擬(軟中斷)。每個信號用一個整型常量宏表示,以SIG開頭,比如SIGCHLD、SIGINT等,它們在系統(tǒng)頭文件中定義,也可以通過在shell下鍵入kill –l查看信號列表,或者鍵入man 7 signal查看更詳細的說明。
信號的生成來自內核,讓內核生成信號的請求來自3個地方:
l???????? 用戶:用戶能夠通過輸入CTRL+c、Ctrl+\,或者是終端驅動程序分配給信號控制字符的其他任何鍵來請求內核產生信號;
l???????? 內核:當進程執(zhí)行出錯時,內核會給進程發(fā)送一個信號,例如非法段存取(內存訪問違規(guī))、浮點數溢出等;
l???????? 進程:一個進程可以通過系統(tǒng)調用kill給另一個進程發(fā)送信號,一個進程可以通過信號和另外一個進程進行通信。
由進程的某個操作產生的信號稱為同步信號(synchronous signals),例如除0;由象用戶擊鍵這樣的進程外部事件產生的信號叫做異步信號。(asynchronous signals)。
?????? 進程接收到信號以后,可以有如下3種選擇進行處理:
l???????? 接收默認處理:接收默認處理的進程通常會導致進程本身消亡。例如連接到終端的進程,用戶按下CTRL+c,將導致內核向進程發(fā)送一個SIGINT的信號,進程如果不對該信號做特殊的處理,系統(tǒng)將采用默認的方式處理該信號,即終止進程的執(zhí)行;
l???????? 忽略信號:進程可以通過代碼,顯示地忽略某個信號的處理,例如:signal(SIGINT,SIGDEF);但是某些信號是不能被忽略的,
l???????? 捕捉信號并處理:進程可以事先注冊信號處理函數,當接收到信號時,由信號處理函數自動捕捉并且處理信號。
?
有兩個信號既不能被忽略也不能被捕捉,它們是SIGKILL和SIGSTOP。即進程接收到這兩個信號后,只能接受系統(tǒng)的默認處理,即終止線程。
2. signal信號處理機制?
可以用函數signal注冊一個信號捕捉函數。原型為:
#include?
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
?
signal 的第1個參數signum表示要捕捉的信號,第2個參數是個函數指針,表示要對該信號進行捕捉的函數,該參數也可以是SIG_DEF(表示交由系統(tǒng)缺省處理,相當于白注冊了)或SIG_IGN(表示忽略掉該信號而不做任何處理)。signal如果調用成功,返回以前該信號的處理函數的地址,否則返回 SIG_ERR。
sighandler_t是信號捕捉函數,由signal函數注冊,注冊以后,在整個進程運行過程中均有效,并且對不同的信號可以注冊同一個信號捕捉函數。該函數只有一個參數,表示信號值。
示例:

1、? 捕捉終端CTRL+c產生的SIGINT信號:
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
?
void SignHandler(int iSignNo)
{
??? printf("Capture sign no:%d/n",iSignNo);?
}
?
int main()
{
??? signal(SIGINT,SignHandler);?
??? while(true)?
??????? sleep(1);?
??? return 0;?
}
該程序運行起來以后,通過按 CTRL+c將不再終止程序的運行。應為CTRL+c產生的SIGINT信號已經由進程中注冊的SignHandler函數捕捉了。該程序可以通過 Ctrl+/終止,因為組合鍵Ctrl+/能夠產生SIGQUIT信號,而該信號的捕捉函數尚未在程序中注冊。
2、? 忽略掉終端CTRL+c產生的SIGINT信號:
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
?
int main()
{
??? signal(SIGINT,SIG_IGN);?
??? while(true)?
??????? sleep(1);?
??? return 0;?
}
該程序運行起來以后,將CTRL+C產生的SIGINT信號忽略掉了,所以CTRL+C將不再能是該進程終止,要終止該進程,可以向進程發(fā)送SIGQUIT信號,即組合鍵CTRL+/
?
3、? 接受信號的默認處理,接受默認處理就相當于沒有寫信號處理程序:
?
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
?
int main()
{
??? signal(SIGINT,DEF);?
??? while(true)?
??????? sleep(1);?
??? return 0;?
}
3. sigaction信號處理機制?
3.1. 信號處理情況分析?
在signal處理機制下,還有許多特殊情況需要考慮:
1、? 冊一個信號處理函數,并且處理完畢一個信號之后,是否需要重新注冊,才能夠捕捉下一個信號;
2、? 如果信號處理函數正在處理信號,并且還沒有處理完畢時,又發(fā)生了一個同類型的信號,這時該怎么處理;
3、? 如果信號處理函數正在處理信號,并且還沒有處理完畢時,又發(fā)生了一個不同類型的信號,這時該怎么處理;
4、? 如果程序阻塞在一個系統(tǒng)調用(如read(...))時,發(fā)生了一個信號,這時是讓系統(tǒng)調用返回錯誤再接著進入信號處理函數,還是先跳轉到信號處理函數,等信號處理完畢后,系統(tǒng)調用再返回。
?
示例:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
?
int g_iSeq=0;
?
void SignHandler(int iSignNo)
{
??? int iSeq=g_iSeq++;?
??? printf("%d Enter SignHandler,signo:%d./n",iSeq,iSignNo);?
??? sleep(3);?
??? printf("%d Leave SignHandler,signo:%d/n",iSeq,iSignNo);?
}
?
int main()
{
??? char szBuf[8];?
??? int iRet;?
??? signal(SIGINT,SignHandler);?
??? signal(SIGQUIT,SignHandler);?
??? do{?
??????? iRet=read(STDIN_FILENO,szBuf,sizeof(szBuf)-1);?
??????? if(iRet<0){?
??????????? perror("read fail.");?
??????????? break;?
??????? }?
????? szBuf[iRet]=0;?
??????? printf("Get: %s",szBuf);?
??? }while(strcmp(szBuf,"quit/n")!=0);?
??? return 0;?
}
程序運行時,針對于如下幾種輸入情況(要輸入得快),看輸出結果:
1、? CTRL+c] [CTRL+c] [CTRL+c]
2、? [CTRL+c] [CTRL+/]
3、? hello [CTRL+/] [Enter]
4、? [CTRL+/] hello [Enter]
5、? hel [CTRL+/] lo[Enter]
?
針對于上面各種情況,不同版本OS可能有不同的響應結果。
3.2. sigaction信號處理注冊?
如果要想用程序控制上述各種情況的響應結果,就必須采用新的信號捕獲機制,即使用sigaction信號處理機制。
函數原型:
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
sigaction也用于注冊一個信號處理函數。
參數signum為需要捕捉的信號;
參數 act是一個結構體,里面包含信號處理函數地址、處理方式等信息。
參數oldact是一個傳出參數,sigaction函數調用成功后,oldact里面包含以前對signum的處理方式的信息。
如果函數調用成功,將返回0,否則返回-1
結構體 struct sigaction(注意名稱與函數sigaction相同)的原型為:
struct sigaction {
??? void (*sa_handler)(int);???????? // 老類型的信號處理函數指針
void (*sa_sigaction)(int, siginfo_t *, void *);//新類型的信號處理函數指針
sigset_t sa_mask;???????????????? // 將要被阻塞的信號集合
int sa_flags;???????????????????????? // 信號處理方式掩碼
void (*sa_restorer)(void);???? // 保留,不要使用。
}
?????? 該結構體的各字段含義及使用方式:
1、字段sa_handler是一個函數指針,用于指向原型為void handler(int)的信號處理函數地址,?????? 即老類型?????? 的信號處理函數;
2、字段sa_sigaction也是一個函數指針,用于指向原型為:
void handler(int iSignNum,siginfo_t *pSignInfo,void *pReserved);
的信號處理函數,即新類型的信號處理函數。
該函數的三個參數含義為:
????????????? iSignNum :傳入的信號
????????????? pSignInfo :與該信號相關的一些信息,它是個結構體
????????????? pReserved :保留,現沒用
3、字段sa_handler和sa_sigaction只應該有一個生效,如果想采用老的信號處理機制,就應該讓sa_handler指向正確的信號處理函數;否則應該讓sa_sigaction指向正確的信號處理函數,并且讓字段 sa_flags包含SA_SIGINFO選項。
4、字段sa_mask是一個包含信號集合的結構體,該結構體內的信號表示在進行信號處理時,將要被阻塞的信號。針對sigset_t結構體,有一組專門的函數對它進行處理,它們是:
????????????? #include <signal.h>?
??????? int sigemptyset(sigset_t *set);?????????????????????????????????? // 清空信號集合set
??????? int sigfillset(sigset_t *set);???????????????????????????????? // 將所有信號填充進set中
??????? int sigaddset(sigset_t *set, int signum);?????????????? // 往set中添加信號signum
??????? int sigdelset(sigset_t *set, int signum);??????????????? // 從set中移除信號signum
??????? int sigismember(const sigset_t *set, int signum); // 判斷signnum是不是包含在set中
?????? 例如,如果打算在處理信號SIGINT時,只阻塞對SIGQUIT信號的處理,可以用如下種方法:
????????????? struct sigaction act;?
????????????? sigemptyset(&act.sa_mask);?
????????????? sigaddset(&act_sa_mask,SIGQUIT);?
????????????? sigaction(SIGINT,&act,NULL);?
5、? 字段sa_flags是一組掩碼的合成值,指示信號處理時所應該采取的一些行為,各掩碼的含義為:
?
掩碼 描述?
SA_RESETHAND 處理完畢要捕捉的信號后,將自動撤消信號處理函數的注冊,即必須再重新注冊信號處理函數,才能繼續(xù)處理接下來產生的信號。該選項不符合一般的信號處理流程,現已經被廢棄。?
SA_NODEFER 在處理信號時,如果又發(fā)生了其它的信號,則立即進入其它信號的處理,等其它信號處理完畢后,再繼續(xù)處理當前的信號,即遞規(guī)地處理。如果sa_flags包含了該掩碼,則結構體sigaction的sa_mask將無效!?
SA_RESTART 如果在發(fā)生信號時,程序正阻塞在某個系統(tǒng)調用,例如調用read()函數,則在處理完畢信號后,接著從阻塞的系統(tǒng)返回。該掩碼符合普通的程序處理流程,所以一般來說,應該設置該掩碼,否則信號處理完后,阻塞的系統(tǒng)調用將會返回失敗!?
SA_SIGINFO 指示結構體的信號處理函數指針是哪個有效,如果sa_flags包含該掩碼,則sa_sigactiion指針有效,否則是sa_handler指針有效。

?
?
?????? 練習與驗證:
針對于先前的5種輸入情況,給下面代碼再添加一些代碼,使之能夠進行如下各種形式的響應:
?????? 1 、[CTRL+c] [CTRL+c]時,第1個信號處理阻塞第2個信號處理;
?????? 2 、[CTRL+c] [CTRL+c]時,第1個信號處理時,允許遞規(guī)地第2個信號處理;
?????? 3 、[CTRL+c] [CTRL+/]時,第1個信號阻塞第2個信號處理;
?????? 4 、read不要因為信號處理而返回失敗結果。
?
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
?
int g_iSeq=0;
?
void SignHandlerNew(int iSignNo,siginfo_t *pInfo,void *pReserved)
{
??? int iSeq=g_iSeq++;?
??? printf("%d Enter SignHandlerNew,signo:%d./n",iSeq,iSignNo);?
??? sleep(3);?
??? printf("%d Leave SignHandlerNew,signo:%d/n",iSeq,iSignNo);?
}
?
int main()
{
??? char szBuf[8];?
??? int iRet;?
??? struct sigaction act;?
??? act.sa_sigaction=SignHandlerNew;?
??? act.sa_flags=SA_SIGINFO;?
????????????? //?
??? sigemptyset(&act.sa_mask);?
?? sigaction(SIGINT,&act,NULL);?
??? sigaction(SIGQUIT,&act,NULL);?
??? do{?
??????? iRet=read(STDIN_FILENO,szBuf,sizeof(szBuf)-1);?
??????? if(iRet<0){?
??????????? perror("read fail.");?
??????????? break;?
??????? }?
??????? szBuf[iRet]=0;?
??????? printf("Get: %s",szBuf);?
??? }while(strcmp(szBuf,"quit/n")!=0);?
??? return 0;?
}
?
3.3. sigprocmask信號阻塞?
函數sigaction中設置的被阻塞信號集合只是針對于要處理的信號,例如
struct sigaction act;
????????????????? sigemptyset(&act.sa_mask);?
????????????? sigaddset(&act.sa_mask,SIGQUIT);?
????????????????? sigaction(SIGINT,&act,NULL);?
?????? 表示只有在處理信號SIGINT時,才阻塞信號SIGQUIT;
?????? 函數sigprocmask是全程阻塞,在sigprocmask中設置了阻塞集合后,被阻塞的信號將不能再被信號處理函數捕捉,直到重新設置阻塞信號集合。
?????? 原型為:
?????? #include <signal.h>?
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
參數how的值為如下3者之一:
?????? a :SIG_BLOCK ,將參數2的信號集合添加到進程原有的阻塞信號集合中
?????? b :SIG_UNBLOCK ,從進程原有的阻塞信號集合移除參數2中包含的信號
?????? c :SIG_SET,重新設置進程的阻塞信號集為參數2的信號集
參數set為阻塞信號集
參數oldset是傳出參數,存放進程原有的信號集。
示例:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
?
int g_iSeq=0;
?
void SignHandlerNew(int iSignNo,siginfo_t *pInfo,void *pReserved)
{
??? int iSeq=g_iSeq++;?
??? printf("%d Enter SignHandlerNew,signo:%d./n",iSeq,iSignNo);?
??? sleep(3);?
??? printf("%d Leave SignHandlerNew,signo:%d/n",iSeq,iSignNo);?
}
?
int main()
{
??? char szBuf[8];?
??? int iRet;?
??? struct sigaction act;?
??? act.sa_sigaction=SignHandlerNew;?
??? act.sa_flags=SA_SIGINFO;?
??? // 屏蔽掉SIGINT 信號,SigHandlerNew 將不能再捕捉SIGINT?
sigset_t sigSet;?
??? sigemptyset(&sigSet);?
??? sigaddset(&sigSet,SIGINT);?
??? sigprocmask(SIG_BLOCK,&sigSet,NULL);?
????????????? //?
??? sigemptyset(&act.sa_mask);?
??? sigaction(SIGINT,&act,NULL);?
??? sigaction(SIGQUIT,&act,NULL);?
??? do{?
??????? iRet=read(STDIN_FILENO,szBuf,sizeof(szBuf)-1);?
??????? if(iRet<0){?
??????????? perror("read fail.");?
??????????? break;?
??????? }?
??????? szBuf[iRet]=0;?
??????? printf("Get: %s",szBuf);?
??? }while(strcmp(szBuf,"quit/n")!=0);?
??? return 0;?
}
?
4. 用程序發(fā)送信號?
4.1. kill信號發(fā)送函數?
原型為:
#include <sys/types.h>
??? #include <signal.h>?
int kill(pid_t pid, int sig);
?????? 參數pid為將要接受信號的進程的pid
?????? 參數sig為要發(fā)送的信號
?????? 如果成功,返回0,否則為-1。
?????? 示例,輸入結束后,將通過發(fā)送信號SIGQUIT把自己殺掉:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
????????????????? while(true){?
?????????????? if(getchar()==EOF)?
??????????? kill(getpid(),SIGQUIT);?
????????????????? }?
??? return 0;?
}
4.2. sigqueue信號發(fā)送函數?
sigqueue也可以發(fā)送信號,并且能傳遞附加的信息。
原型為:
#include <signal.h>
??? int sigqueue(pid_t pid, int sig, const union sigval value);?
參數pid為接收信號的進程;
參數sig為要發(fā)送的信號;
參數value為一整型與指針類型的聯合體:
?????? union sigval {?
int?? sival_int;?
void *sival_ptr;
??? };?
由sigqueue函數發(fā)送的信號的第3個參數value的值,可以被進程的信號處理函數的第2個參數info->si_ptr接收到。
示例1,進程給自己發(fā)信號,并且?guī)细郊有畔?#xff1a;
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
?
void SignHandlerNew(int signum,siginfo_t *info,void *myact)
{
????????????????? char *pszInfo=(char *)(info->si_ptr);?
??? printf("Get:%d info:%s/n",signum,pszInfo);?
}
?
int main(int argc,char**argv)
{
????????????????? struct sigaction act;???
??? union sigval mysigval;?
????????????????? int sig;?
??? char data[]="other info";?
????????????????? //?
????????????????? if(argc<2){?
????????????????????? printf("usage: SIGNNUM/n");?
??????? return -1;?
????????????????? }?
??? mysigval.sival_ptr=data;?
????????????????? sig=atoi(argv[1]);?
??? sigemptyset(&act.sa_mask);?
????????? act.sa_sigaction=SignHandlerNew;?
????????????????? act.sa_flags=SA_SIGINFO;?
????????????????? sigaction(sig,&act,NULL);?
????????????????? while(true){?
????????????????????? printf("wait for the signal/n");?
????????????????????? sigqueue(getpid(),sig,mysigval);?
????????????????????? sleep(2);?
????????????????? }?
}
?
示例2:一個進程向另外一個進程發(fā)送信號。注意:發(fā)送進程不要將自己進程空間的地址發(fā)送給接收進程,因為接收進程接收到地址也訪問不到發(fā)送進程的地址空間的。
?
示例2信號接收程序:
?????? #include <signal.h>?
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
?
void SignHandlerNew(int signum,siginfo_t *info,void *myact)
{
????????????????? printf("Get:%d info:%d/n",signum,info->si_int);?
}
?
int main(int argc,char**argv)
{
????????????????? struct sigaction act;?
??? //?
????????????????? if(argc<2){?
????????????????????? printf("usage: signnum/n");?
??????? return -1;?
????????????????? }?
??? sigemptyset(&act.sa_mask);?
??? act.sa_sigaction=SignHandlerNew;?
????????????????? act.sa_flags=SA_SIGINFO;?
??? sigaction(atoi(argv[1]),&act,NULL);?
????????????????? while(1)?
??? {?
????????????????????? printf("wait for the signal/n");?
?????????????? sleep(2);?
??? }?
????????????????? return 0;?
}
???????
示例2信號發(fā)送程序:
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
?
int main(int argc,char**argv)
{
????????????????? union sigval mysigval;?
??? int iPid,iSignNo,iData;?
????????????????? //?
??? if(argc<4){?
????????????????????? printf("usage: pid signnum data/n");?
????????????????????? return -1;?
}
??? iPid=atoi(argv[1]);?
????????????????? iSignNo=atoi(argv[2]);?
??? iData=atoi(argv[3]);?
??? mysigval.sival_int=iData;?
????????????????? if(sigqueue(iPid,iSignNo,mysigval)<0)?
????????????????????? perror("Send signal fail.");?
??? return 0;?
}?????
???????
5. 計時器與信號?
5.1. 睡眠函數?
Linux下有兩個睡眠函數,原型為:
?????? #include <unistd.h>?
??????? unsigned int sleep(unsigned int seconds);?
????????????? void usleep(unsigned long usec);?
?????? 函數sleep讓進程睡眠seconds秒,函數usleep讓進程睡眠usec毫秒。
?????? sleep 睡眠函數內部是用信號機制進行處理的,用到的函數有:
????????????? #include <unistd.h>?
unsigned int alarm(unsigned int seconds);???? // 告知自身進程,要進程在seconds秒后自動產生一個//SIGALRM的信號,
int pause(void);?????????????????????? // 將自身進程掛起,直到有信號發(fā)生時才從pause返回
???????
?????? 示例:模擬睡眠3秒:
????????????? #include <signal.h>?
#include <stdio.h>
#include <unistd.h>
?
void SignHandler(int iSignNo)
{
??? printf("signal:%d/n",iSignNo);?
}
?
int main()
{
??? signal(SIGALRM,SignHandler);?
??? alarm(3);?
??? printf("Before pause()./n");?
??? pause();?
??? printf("After pause()./n");?
??? return 0;?
}
注意:因為sleep在內部是用alarm實現的,所以在程序中最好不要sleep與alarm混用,以免造成混亂。
5.2. 時鐘處理???
Linux為每個進程維護3個計時器,分別是真實計時器、虛擬計時器和實用計時器。
l???????? 真實計時器計算的是程序運行的實際時間;
l???????? 虛擬計時器計算的是程序運行在用戶態(tài)時所消耗的時間(可認為是實際時間減掉(系統(tǒng)調用和程序睡眠所消耗)的時間);
l???????? 實用計時器計算的是程序處于用戶態(tài)和處于內核態(tài)所消耗的時間之和。
例如:有一程序運行,在用戶態(tài)運行了5秒,在內核態(tài)運行了6秒,還睡眠了7秒,則真實計算器計算的結果是18秒,虛擬計時器計算的是5秒,實用計時器計算的是11秒。
用指定的初始間隔和重復間隔時間為進程設定好一個計時器后,該計時器就會定時地向進程發(fā)送時鐘信號。3個計時器發(fā)送的時鐘信號分別為:SIGALRM,SIGVTALRM和SIGPROF。
用到的函數與數據結構:
#include <sys/time.h>
?
//獲取計時器的設置
//which指定哪個計時器,可選項為ITIMER_REAL(真實計時器)、ITIMER_VITUAL(虛擬計時器、ITIMER_PROF(實用計時器))
//value為一結構體的傳出參數,用于傳出該計時器的初始間隔時間和重復間隔時間
//如果成功,返回0,否則-1
int getitimer(int which, struct itimerval *value);
?
//設置計時器
//which指定哪個計時器,可選項為ITIMER_REAL(真實計時器)、ITIMER_VITUAL(虛擬計時器、ITIMER_PROF(實用計時器))
//value為一結構體的傳入參數,指定該計時器的初始間隔時間和重復間隔時間
//ovalue為一結構體傳出參數,用于傳出以前的計時器時間設置。
//如果成功,返回0,否則-1
int setitimer(int which, const struct itimerval *value, struct itimer val *ovalue);
????
struct itimerval {
struct timeval it_interval; /* next value */??????????? // 重復間隔
struct timeval it_value;??? /* current value */???? // 初始間隔?????
};
struct timeval {
long tv_sec;??????????????? /* seconds */??????????????????? // 時間的秒數部分
long tv_usec;?????????????? /* microseconds */??????? // 時間的微秒部分
};
?
示例:啟用真實計時器的進行時鐘處理
??????????? #include <stdio.h>?
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
?
void TimeInt2Obj(int imSecond,timeval *ptVal)
{
ptVal->tv_sec=imSecond/1000;
??????? ptVal->tv_usec=(imSecond%1000)*1000;?
}
?
void SignHandler(int SignNo)
{
printf("Clock/n");
}
?
int main()
{
signal(SIGALRM,SignHandler);
??? itimerval tval;?
??? TimeInt2Obj(1,&tval.it_value);??????????? // 設初始間隔為1毫秒,注意不要為0
????????????? TimeInt2Obj(1500,&tval.it_interval);??? // 設置以后的重復間隔為1500毫秒
??? setitimer(ITIMER_REAL,&tval,NULL);?
?????????????? while(getchar()!=EOF);?
??? return 0;?
}

SIGHUP???? 終止進程???? 終端線路掛斷
SIGINT???? 終止進程???? 中斷進程
SIGQUIT?? 建立CORE文件終止進程,并且生成core文件
SIGILL?? 建立CORE文件?????? 非法指令
SIGTRAP?? 建立CORE文件?????? 跟蹤自陷
SIGBUS?? 建立CORE文件?????? 總線錯誤
SIGSEGV?? 建立CORE文件?????? 段非法錯誤
SIGFPE?? 建立CORE文件?????? 浮點異常
SIGIOT?? 建立CORE文件?????? 執(zhí)行I/O自陷
SIGKILL?? 終止進程???? 殺死進程
SIGPIPE?? 終止進程???? 向一個沒有讀進程的管道寫數據
SIGALARM?? 終止進程???? 計時器到時
SIGTERM?? 終止進程???? 軟件終止信號
SIGSTOP?? 停止進程???? 非終端來的停止信號
SIGTSTP?? 停止進程???? 終端來的停止信號
SIGCONT?? 忽略信號???? 繼續(xù)執(zhí)行一個停止的進程
SIGURG?? 忽略信號???? I/O緊急信號
SIGIO???? 忽略信號???? 描述符上可以進行I/O
SIGCHLD?? 忽略信號???? 當子進程停止或退出時通知父進程
SIGTTOU?? 停止進程???? 后臺進程寫終端
SIGTTIN?? 停止進程???? 后臺進程讀終端
SIGXGPU?? 終止進程???? CPU時限超時
SIGXFSZ?? 終止進程???? 文件長度過長
SIGWINCH?? 忽略信號???? 窗口大小發(fā)生變化
SIGPROF?? 終止進程???? 統(tǒng)計分布圖用計時器到時
SIGUSR1?? 終止進程???? 用戶定義信號1
SIGUSR2?? 終止進程???? 用戶定義信號2
SIGVTALRM 終止進程???? 虛擬計時器到時

總結

以上是生活随笔為你收集整理的linux 信号处理函数详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。