信號處理函數

信號處理函數


sigaction的用法

int sigaction (

????????int signo,

????????const struct sigaction *act,

????????struct sigaction *oldact

);

這個函數主要是用于改變或檢測信號的行為融击。

第一個參數是變更signo指定的信號吗购,它可以指向任何值则拷,SIGKILL,SIGSTOP除外

第二個參數,第三個參數是對信號進行細粒度的控制。

如果*act不為空向叉,*oldact不為空糖权,那么oldact將會存儲信號以前的行為。

如果act為空,*oldact不為空铜幽,那么oldact將會存儲信號現在的行為。

struct sigaction? {

????????void (*sa_handler)(int);

????????void (*sa_sigaction)(int, siginfo_t*, void*);

????????sigset_t sa_mask;

????????int sa_flags;

????????void (*sa_restorer)(void);

}

參數含義:

sa_handler是一個函數指針串稀,主要是表示接收到信號時所要采取的行動除抛。此字段的值可以是SIG_DFL,SIG_IGN.分別代表默認操作與內核將忽略進程的信號。這個函數只傳遞一個參數那就是信號代碼母截。

當SA_SIGINFO被設定在sa_flags中镶殷,那么則會使用sa_sigaction來指示信號處理函數,而非sa_handler.

sa_mask設置了掩碼集微酬,在程序執(zhí)行期間會阻擋掩碼集中的信號绘趋。

sa_flags設置了一些標志, SA_RESETHAND當該函數處理完成之后颗管,設定為為系統(tǒng)默認的處理模式陷遮。SA_NODEFER 在處理函數中,如果再次到達此信號時垦江,將不會阻塞帽馋。默認情況下,同一信號兩次到達時,如果此時處于信號處理程序中绽族,那么此信號將會阻塞姨涡。

SA_SIGINFO表示用sa_sigaction指示的函數。

sa_restorer已經被廢棄吧慢。

sa_sigaction所指向的函數原型:

void my_handler(int signo, siginfo_t *si, void *ucontext);

第一個參數: 信號編號

第二個參數:指向一個siginfo_t結構涛漂。

第三個參數是一個ucontext_t結構。

其中siginfo_t結構體中包含了大量的信號攜帶信息检诗,可以看出匈仗,這個函數比sa_handler要強大,因為前者只能傳遞一個信號代碼逢慌,而后者可以傳遞siginfo_t信息悠轩。

typedef struct siginfo_t {

????????int si_signo;//信號編號

????????int si_errno;//如果為非零值則錯誤代碼與之關聯

????????int si_code;//說明進程如何接收信號以及從何處收到

????????pid_t si_pid;//適用于SIGCHLD,代表被終止進程的PID

????????pid_t si_uid;//適用于SIGCHLD,代表被終止進程所擁有進程的UID

????????int si_status;//適用于SIGCHLD攻泼,代表被終止進程的狀態(tài)

????????clock_t si_utime;//適用于SIGCHLD火架,代表被終止進程所消耗的用戶時間

????????clock_t si_stime;//適用于SIGCHLD,代表被終止進程所消耗系統(tǒng)的時間

????????sigval_t si_value;

????????int si_int;

????????void * si_ptr;

????????void* si_addr;

????????int si_band;

????????int si_fd;

};

sigqueue的用法

sigqueue( pid_t pid, int signo, const union sigval value)

union sigval? {int sival_int, void*sival_ptr };

sigqueue函數類似于kill,也是一個進程向另外一個進程發(fā)送信號的忙菠。

但它比kill函數強大何鸡。

第一個參數指定目標進程的pid.

第二個參數是一個信號代碼。

第三個參數是一個共用體只搁,每次只能使用一個音比,用來進程發(fā)送信號傳遞的數據俭尖。

或者傳遞整形數據氢惋,或者是傳遞指針。

發(fā)送的數據被sa_sigaction所指示的函數的siginfo_t結構體中的si_ptr或者是si_int所接收稽犁。

sigpending的用法

sigpending(sigset_t set);

這個函數的作用是返回未決的信號到信號集set中焰望。

即未決信號集,未決信號集不僅包括被阻塞的信號已亥,也可能包括已經到達但沒有被處理的信號熊赖。

示例1: sigaction函數的用法

void signal_set1(int x) { //信號處理函數,只傳遞一個參數信號代碼

????????printf("xxxxx/n");

????????while(1)? {

????????????????//

?????????}

}

void signal_set(struct sigaction *act)

{

????????switch(act->sa_flags) {

????????case (int)SIG_DFL:

????????????????printf("using default hander/n");

????????????????break;

????????case (int)SIG_IGN:

????????????????printf("ignore the signal/n");

????????????????break;

????????default:

????????????????printf("%0x/n",act->sa_handler);

????????}

}

int main(int argc, char** argv)

{

????????int i;

????????struct sigaction act,oldact;

????????act.sa_handler = signal_set1;

????????act.sa_flags = SA_RESETHAND;

????????//SA_RESETHANDD 在處理完信號之后虑椎,將信號恢復成默認處理

????????//SA_NODEFER在信號處理程序執(zhí)行期間仍然可以接收信號

????????sigaction (SIGINT,&act,&oldact) ;//改變信號的處理模式

????????for (i=1; i<12; i++)

????????{

????????????????printf("signal %d handler is : ",i);

????????????????sigaction (i,NULL,&oldact) ;

????????????????signal_set(&oldact);//如果act為NULL震鹉,oldact會存儲信號當前的行為

????????????????//act不為空,oldact不為空捆姜,則oldact會存儲信號以前的處理模式

????????}

????????while(1) {

????????????????//等待信號的到來

????????}

????????return 0;

}

運行結果:

[root@localhost C]# ./s2

signal 1 handler is : using default hander

signal 2 handler is : 8048437

signal 3 handler is : using default hander

signal 4 handler is : using default hander

signal 5 handler is : using default hander

signal 6 handler is : using default hander

signal 7 handler is : using default hander

signal 8 handler is : using default hander

signal 9 handler is : using default hander

signal 10 handler is : using default hander

signal 11 handler is : using default hander

xxxxx

解釋:

sigaction(i,NULL,&oldact);

signal_set(&oldact);

由于act為NULL,那么oldact保存的是當前信號的行為传趾,當前的第二個信號的行為是執(zhí)行自定義的處理程序。

當按下CTRL+C時會執(zhí)行信號處理程序泥技,輸出xxxxxx浆兰,再按一下CTRL+C會停止,是由于SA_RESETHAND恢復成默認的處理模式,即終止程序。

如果沒有設置SA_NODEFER,那么在處理函數執(zhí)行過程中按一下CTRL+C將會被阻塞簸呈,那么程序會停在那里榕订。


示例2: sigqueue向本進程發(fā)送數據的信號

void myhandler(int signo, siginfo_t *si, void *ucontext);

int main()? {

????????union sigval val;//定義一個攜帶數據的共用體

????????struct sigaction oldact,act;

????????act.sa_sigaction = myhandler;

????????act.sa_flags = SA_SIGINFO;//表示使用sa_sigaction指示的函數,處理完恢復默認蜕便,不阻塞處理過程中到達下在被處理的信號

????????//注冊信號處理函數

????????sigaction(SIGUSR1, &act, &oldact);

????????char data[100];

????????int num=0;

????????while( num < 10 )? {

????????????????sleep( 2 );

????????????????printf("等待SIGUSR1信號的到來/n");

????????????????sprintf(data, "%d", num++);

????????????????val.sival_ptr=data;

????????????????sigqueue( getpid(), SIGUSR1, val );//向本進程發(fā)送一個信號

????????????}

}

void myhandler ( int signo, siginfo_t *si, void *ucontext )? {

????????printf("已經收到SIGUSR1信號/n");

????????printf("%s/n",(char*)(si->si_ptr));

}

程序執(zhí)行的結果是:

等待SIGUSR1信號的到來

已經收到SIGUSR1信號

0

等待SIGUSR1信號的到來

已經收到SIGUSR1信號

1

等待SIGUSR1信號的到來

已經收到SIGUSR1信號

2

等待SIGUSR1信號的到來

已經收到SIGUSR1信號

3

等待SIGUSR1信號的到來

已經收到SIGUSR1信號

4

等待SIGUSR1信號的到來

已經收到SIGUSR1信號

5

等待SIGUSR1信號的到來

已經收到SIGUSR1信號

6

等待SIGUSR1信號的到來

已經收到SIGUSR1信號

7

等待SIGUSR1信號的到來

已經收到SIGUSR1信號

8

等待SIGUSR1信號的到來

已經收到SIGUSR1信號

9

解釋:?

本程序用sigqueue不停的向自身發(fā)送信號,并且攜帶數據劫恒,數據被放到處理函數的第二個參數siginfo_t結構體中的si_ptr指針,當num<10時不再發(fā)玩裙。

一般而言兼贸,sigqueue與sigaction配合使用,而kill與signal配合使用吃溅。


示例3: 一個進程向另外一個進程發(fā)送信號溶诞,并攜帶信息

發(fā)送端:

int main()? {

????????union sigval value;

????????value.sival_int=10;

????????if ( sigqueue(4403, SIGUSR1, value) == -1 )? {? //4403是目標進程pid

????????????????perror("信號發(fā)送失敗/n");

????????}

????????sleep(2);

}

接收端:

void myhandler ( int signo, siginfo_t*si, void *ucontext );

int main () {

????????struct sigaction oldact, act;

????????act.sa_sigaction = myhandler;

????????act.sa_flags = SA_SIGINFO | SA_NODEFER;

????????//表示執(zhí)行后恢復,用sa_sigaction指示的處理函數决侈,在執(zhí)行期間仍然可以接收信號

????????sigaction ( SIGUSR1, &act, &oldact );

????????while ( 1 )? {

????????????????sleep ( 2 );

????????????????printf("等待信號的到來/n");

????????}

}

void myhandler ( int signo, siginfo_t *si, void *ucontext ) {

????????printf("the value is %d/n",si->si_int);

}


示例4: sigpending的用法

sigpending (sigset_t *set )將未決信號放到指定的set信號集中去螺垢,未決信號包括被阻塞的信號和信號到達時但還沒來得及處理的信號

void myhandler ( int signo, siginfo_t *si, void *ucontext );

int main()? {

????????struct sigaction oldact, act;

????????sigset_t oldmask, newmask, pendingmask;

????????act.sa_sigaction = myhandler;

????????act.sa_flags = SA_SIGINFO;

????????sigemptyset( &act.sa_mask );? //首先將阻塞集合設置為空,即不阻塞任何信號

????????//注冊信號處理函數

????????sigaction(SIGRTMIN + 10, &act ,&oldact);

????????//開始阻塞

????????sigemptyset( &newmask );

????????sigaddset( &newmask, SIGRTMIN + 10);

????????printf("SIGRTMIN + 10 blocked/n");

????????sigprocmask( SIG_BLOCK , &newmask ,&oldmask );

????????sleep(20);? //為了發(fā)出信號

????????printf("now begin to get pending mask/n");

????????if ( sigpending( &pendingmask ) < 0 )? {

????????????????perror("pendingmask error");

????????}

????????if ( sigismember( &pendingmask, SIGRTMIN + 10 ) )? {

????????????????printf("SIGRTMIN+10 is in the pending mask/n");

????????}

????????sigprocmask( SIG_UNBLOCK, &newmask, &oldmask);

? ? ? ? printf("SIGRTMIN+10 unblocked/n");

}

//信號處理函數

void myhandler ( int signo, siginfo_t *si, void *ucontext )? {

????????printf("receive signal %d/n",si->si_signo);

}

程序執(zhí)行:

在另一個shell發(fā)送信號:

kill -44 4579

SIGRTMIN +10 blocked

now begin to get pending mask

SIGRTMIN +10 is in the pending mask

receive signal 44

SIGRTMIN +10 unblocked

可以看到SIGRTMIN由于被阻塞所以處于未決信號集中赖歌。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末枉圃,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子庐冯,更是在濱河造成了極大的恐慌孽亲,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件展父,死亡現場離奇詭異返劲,居然都是意外死亡,警方通過查閱死者的電腦和手機栖茉,發(fā)現死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門篮绿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吕漂,你說我怎么就攤上這事亲配。” “怎么了惶凝?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵吼虎,是天一觀的道長。 經常有香客問我苍鲜,道長思灰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任坡贺,我火速辦了婚禮官辈,結果婚禮上箱舞,老公的妹妹穿的比我還像新娘。我一直安慰自己拳亿,他們只是感情好晴股,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肺魁,像睡著了一般电湘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鹅经,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天寂呛,我揣著相機與錄音,去河邊找鬼瘾晃。 笑死贷痪,一個胖子當著我的面吹牛,可吹牛的內容都是我干的蹦误。 我是一名探鬼主播劫拢,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼强胰!你這毒婦竟也來了舱沧?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤偶洋,失蹤者是張志新(化名)和其女友劉穎熟吏,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體玄窝,經...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡牵寺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了哆料。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缸剪。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡吗铐,死狀恐怖东亦,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情唬渗,我是刑警寧澤典阵,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站镊逝,受9級特大地震影響壮啊,放射性物質發(fā)生泄漏。R本人自食惡果不足惜撑蒜,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一歹啼、第九天 我趴在偏房一處隱蔽的房頂上張望玄渗。 院中可真熱鬧,春花似錦狸眼、人聲如沸藤树。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岁钓。三九已至,卻和暖如春微王,著一層夾襖步出監(jiān)牢的瞬間屡限,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工炕倘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钧大,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓罩旋,卻偏偏與公主長得像拓型,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子瘸恼,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內容

  • 信號的基本概念 信號被認為是一種軟件中斷(區(qū)別于硬件中斷),信號機制提供了一種在單進程/線程下處理異步事件的方法劣挫。...
    小葉大孟閱讀 1,898評論 0 1
  • 信號(signal)是一種軟件中斷压固,它提供了一種處理異步事件的方法,也是進程間惟一的異步通信方式靠闭。在Linux系統(tǒng)...
    夏大王2019閱讀 997評論 0 1
  • 對于 Linux來說帐我,實際信號是軟中斷,許多重要的程序都需要處理信號愧膀。信號拦键,為 Linux 提供了一種處理異步事件...
    故事狗閱讀 84,754評論 2 62
  • 生理節(jié)奏 所有的生命都受到日--夜這種自然節(jié)律的影響。你的身體受一種被稱作生理節(jié)律的時間周期所調節(jié):你的喚醒水平檩淋、...
    牧明不是木牧閱讀 357評論 0 1
  • 1芬为、感賞我的生命中出現的每一個人,其實每一個人都有不易的地方蟀悦,可是每一個人都在努力的活著媚朦,并努力的活好,自己也是每...
    后來來了閱讀 187評論 0 2