linux內(nèi)核中的信號(hào)機(jī)制--從用戶層到內(nèi)核層
CPU architecture:ARM920T
本文引用地址:http://m.butianyuan.cn/article/201611/320007.htmAuthor:ce123(http://blog.csdn.net/ce123)
1.簡(jiǎn)介
如果進(jìn)程要處理某一信號(hào),那么要在進(jìn)程中注冊(cè)該信號(hào)。注冊(cè)信號(hào)主要用來(lái)確定信號(hào)值及進(jìn)程針對(duì)該信號(hào)值的動(dòng)作之間的映射關(guān)系,即進(jìn)程將要處理哪個(gè)進(jìn)程和該信號(hào)被傳遞給進(jìn)程時(shí),將執(zhí)行何種操作。主要有兩個(gè)函數(shù)實(shí)現(xiàn)信號(hào)的注冊(cè):signal()和sigaction()。
2.signal()
signal()的函數(shù)原型如下:
- void(*signal(intsignum,void(*handler)(int)))(int);
- #include
上述聲明格式比較復(fù)雜,如果不清楚如何使用,也可以通過(guò)下面這種類型定義的格式來(lái)使用(POSIX的定義):
- typedefvoid(*sighandler_t)(int);
- sighandler_tsignal(intsignum,sighandler_thandler);
- SIG_IGN:忽略參數(shù)signum所指的信號(hào)。
- SIG_DFL:恢復(fù)參數(shù)signum所指信號(hào)的處理方法為默認(rèn)值。
signal()通過(guò)系統(tǒng)調(diào)用sys_signal()為一個(gè)指定的信號(hào)設(shè)置用戶態(tài)處理函數(shù)。sys_signal()定義如下:
- /*
- *Forbackwardscompatibility.Functionalitysupersededbysigaction.
- */
- asmlinkageunsignedlong
- sys_signal(intsig,__sighandler_thandler)
- {
- structk_sigactionnew_sa,old_sa;
- intret;
- new_sa.sa.sa_handler=handler;
- new_sa.sa.sa_flags=SA_ONESHOT|SA_NOMASK;
- ret=do_sigaction(sig,&new_sa,&old_sa);
- returnret?ret:(unsignedlong)old_sa.sa.sa_handler;
- }
__sighandler_t的定義如下:
- typedefvoid__signalfn_t(int);
- typedef__signalfn_t__user*__sighandler_t;
信號(hào)由sys_signal()的第一個(gè)參數(shù)指定,信號(hào)處理函數(shù)的地址由第二個(gè)參數(shù)指定。sys_signal()根據(jù)這兩個(gè)參數(shù)設(shè)置一個(gè)k_sigaction結(jié)構(gòu),然后調(diào)用do_sigaction(),該函數(shù)的定義我們會(huì)在后面具體講解。
2.sigaction()
sigaction()的函數(shù)原型如下:
- sigaction(intsignum,conststructsigaction*act,structsigaction*oldact);
2.1do_sigaction()
- int
- do_sigaction(intsig,conststructk_sigaction*act,structk_sigaction*oact)
- {
- structk_sigaction*k;
- if(!valid_signal(sig)||sig<1||(act&&sig_kernel_only(sig)))
- return-EINVAL;
- k=¤tt->sighand->action[sig-1];
- spin_lock_irq(¤tt->sighand->siglock);
- if(signal_pending(current)){
- /*
- *Iftheremightbeafatalsignalpendingonmultiple
- *threads,makesurewetakeitbeforechangingtheaction.
- */
- spin_unlock_irq(¤tt->sighand->siglock);
- return-ERESTARTNOINTR;
- }
- if(oact)//把原來(lái)的k_sigaction保存到oact結(jié)構(gòu)中,這里是對(duì)整個(gè)數(shù)據(jù)結(jié)構(gòu)進(jìn)行復(fù)制
- *oact=*k;
- if(act){
- /*
- *POSIX3.3.1.3:
- *"SettingasignalactiontoSIG_IGNforasignalthatis
- *pendingshallcausethependingsignaltobediscarded,
- *whetherornotitisblocked."
- *
- *"SettingasignalactiontoSIG_DFLforasignalthatis
- *pendingandwhosedefaultactionistoignorethesignal
- *(forexample,SIGCHLD),shallcausethependingsignalto
- *bediscarded,whetherornotitisblocked"
- */
- if(act->sa.sa_handler==SIG_IGN||
- (act->sa.sa_handler==SIG_DFL&&
- sig_kernel_ignore(sig))){
- /*
- *Thisisafairlyrarecase,soweonlytakethe
- *tasklist_lockonceweresurewellneedit.
- *Nowwemustdothislittleunlockandrelock
- *dancetomaintainthelockhierarchy.
- */
- structtask_struct*t=current;
- spin_unlock_irq(&t->sighand->siglock);
- read_lock(&tasklist_lock);
- spin_lock_irq(&t->sighand->siglock);
- *k=*act;//把新的k_sigaction結(jié)構(gòu)復(fù)制到進(jìn)程的sighand->action中
- sigdelsetmask(&k->sa.sa_mask,
- sigmask(SIGKILL)|sigmask(SIGSTOP));
- rm_from_queue(sigmask(sig),&t->signal->shared_pending);
- do{
- rm_from_queue(sigmask(sig),&t->pending);
- recalc_sigpending_tsk(t);
- t=next_thread(t);
- }while(t!=current);
- spin_unlock_irq(¤t->sighand->siglock);
- read_unlock(&tasklist_lock);
- return0;
- }
- *k=*act;//把新的k_sigaction結(jié)構(gòu)復(fù)制到進(jìn)程的sighand->action中
- sigdelsetmask(&k->sa.sa_mask,
- sigmask(SIGKILL)|sigmask(SIGSTOP));
- }
- spin_unlock_irq(¤tt->sighand->siglock);
- return0;
- }
評(píng)論