新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應用 > linux內(nèi)核中的信號機制--從用戶層到內(nèi)核層

        linux內(nèi)核中的信號機制--從用戶層到內(nèi)核層

        作者: 時間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
        Kernel version:2.6.14

        CPU architecture:ARM920T

        本文引用地址:http://www.104case.com/article/201611/320007.htm

        Author:ce123(http://blog.csdn.net/ce123)


        1.簡介

        如果進程要處理某一信號,那么要在進程中注冊該信號。注冊信號主要用來確定信號值及進程針對該信號值的動作之間的映射關(guān)系,即進程將要處理哪個進程和該信號被傳遞給進程時,將執(zhí)行何種操作。主要有兩個函數(shù)實現(xiàn)信號的注冊:signal()和sigaction()。

        2.signal()

        signal()的函數(shù)原型如下:

        [plain]view plaincopy
        print?
        1. void(*signal(intsignum,void(*handler)(int)))(int);
        在使用該調(diào)用的進程中加入以下頭文件:
        [plain]view plaincopy
        print?
        1. #include

        上述聲明格式比較復雜,如果不清楚如何使用,也可以通過下面這種類型定義的格式來使用(POSIX的定義):

        [plain]view plaincopy
        print?
        1. typedefvoid(*sighandler_t)(int);
        2. sighandler_tsignal(intsignum,sighandler_thandler);
        但這種格式在不同的系統(tǒng)中有不同的類型定義,所以要使用這種格式,最好還是參考一下手冊。在調(diào)用中,參數(shù)signum指出要設(shè)置處理方法的信號。第二個參數(shù)handler是一個處理函數(shù),或者是
        • SIG_IGN:忽略參數(shù)signum所指的信號。
        • SIG_DFL:恢復參數(shù)signum所指信號的處理方法為默認值。
        傳遞給信號處理例程的整數(shù)參數(shù)是信號值,這樣可以使得一個信號處理例程處理多個信號。系統(tǒng)調(diào)用signal()返回值是指定信號signum前一次的處理例程或者錯誤時返回錯誤代碼SIG_ERR。

        signal()通過系統(tǒng)調(diào)用sys_signal()為一個指定的信號設(shè)置用戶態(tài)處理函數(shù)。sys_signal()定義如下:

        [plain]view plaincopy
        print?
        1. /*
        2. *Forbackwardscompatibility.Functionalitysupersededbysigaction.
        3. */
        4. asmlinkageunsignedlong
        5. sys_signal(intsig,__sighandler_thandler)
        6. {
        7. structk_sigactionnew_sa,old_sa;
        8. intret;
        9. new_sa.sa.sa_handler=handler;
        10. new_sa.sa.sa_flags=SA_ONESHOT|SA_NOMASK;
        11. ret=do_sigaction(sig,&new_sa,&old_sa);
        12. returnret?ret:(unsignedlong)old_sa.sa.sa_handler;
        13. }

        __sighandler_t的定義如下:

        [plain]view plaincopy
        print?
        1. typedefvoid__signalfn_t(int);
        2. typedef__signalfn_t__user*__sighandler_t;

        信號由sys_signal()的第一個參數(shù)指定,信號處理函數(shù)的地址由第二個參數(shù)指定。sys_signal()根據(jù)這兩個參數(shù)設(shè)置一個k_sigaction結(jié)構(gòu),然后調(diào)用do_sigaction(),該函數(shù)的定義我們會在后面具體講解。

        2.sigaction()

        sigaction()的函數(shù)原型如下:

        [plain]view plaincopy
        print?
        1. sigaction(intsignum,conststructsigaction*act,structsigaction*oldact);
        sigaction()對應的系統(tǒng)調(diào)用為do_sigaction(),下面我們具體講解do_sigaction()函數(shù),其定義如下:

        2.1do_sigaction()

        [plain]view plaincopy
        print?
        1. int
        2. do_sigaction(intsig,conststructk_sigaction*act,structk_sigaction*oact)
        3. {
        4. structk_sigaction*k;
        5. if(!valid_signal(sig)||sig<1||(act&&sig_kernel_only(sig)))
        6. return-EINVAL;
        7. k=¤tt->sighand->action[sig-1];
        8. spin_lock_irq(¤tt->sighand->siglock);
        9. if(signal_pending(current)){
        10. /*
        11. *Iftheremightbeafatalsignalpendingonmultiple
        12. *threads,makesurewetakeitbeforechangingtheaction.
        13. */
        14. spin_unlock_irq(¤tt->sighand->siglock);
        15. return-ERESTARTNOINTR;
        16. }
        17. if(oact)//把原來的k_sigaction保存到oact結(jié)構(gòu)中,這里是對整個數(shù)據(jù)結(jié)構(gòu)進行復制
        18. *oact=*k;
        19. if(act){
        20. /*
        21. *POSIX3.3.1.3:
        22. *"SettingasignalactiontoSIG_IGNforasignalthatis
        23. *pendingshallcausethependingsignaltobediscarded,
        24. *whetherornotitisblocked."
        25. *
        26. *"SettingasignalactiontoSIG_DFLforasignalthatis
        27. *pendingandwhosedefaultactionistoignorethesignal
        28. *(forexample,SIGCHLD),shallcausethependingsignalto
        29. *bediscarded,whetherornotitisblocked"
        30. */
        31. if(act->sa.sa_handler==SIG_IGN||
        32. (act->sa.sa_handler==SIG_DFL&&
        33. sig_kernel_ignore(sig))){
        34. /*
        35. *Thisisafairlyrarecase,soweonlytakethe
        36. *tasklist_lockonceweresurewellneedit.
        37. *Nowwemustdothislittleunlockandrelock
        38. *dancetomaintainthelockhierarchy.
        39. */
        40. structtask_struct*t=current;
        41. spin_unlock_irq(&t->sighand->siglock);
        42. read_lock(&tasklist_lock);
        43. spin_lock_irq(&t->sighand->siglock);
        44. *k=*act;//把新的k_sigaction結(jié)構(gòu)復制到進程的sighand->action中
        45. sigdelsetmask(&k->sa.sa_mask,
        46. sigmask(SIGKILL)|sigmask(SIGSTOP));
        47. rm_from_queue(sigmask(sig),&t->signal->shared_pending);
        48. do{
        49. rm_from_queue(sigmask(sig),&t->pending);
        50. recalc_sigpending_tsk(t);
        51. t=next_thread(t);
        52. }while(t!=current);
        53. spin_unlock_irq(¤t->sighand->siglock);
        54. read_unlock(&tasklist_lock);
        55. return0;
        56. }
        57. *k=*act;//把新的k_sigaction結(jié)構(gòu)復制到進程的sighand->action中
        58. sigdelsetmask(&k->sa.sa_mask,
        59. sigmask(SIGKILL)|sigmask(SIGSTOP));
        60. }
        61. spin_unlock_irq(¤tt->sighand->siglock);
        62. return0;
        63. }



        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 互助| 千阳县| 寿阳县| 龙江县| 昌图县| 宁德市| 上林县| 宜兴市| 漳平市| 新兴县| 靖江市| 茶陵县| 上林县| 东兴市| 沙洋县| 滕州市| 固阳县| 望江县| 怀宁县| 宜兰市| 思茅市| 商丘市| 当阳市| 武川县| 宾阳县| 张家港市| 洮南市| 定西市| 芜湖市| 互助| 汶上县| 浪卡子县| 建湖县| 惠州市| 鄯善县| 舒兰市| 铜山县| 灌南县| 浦江县| 防城港市| 墨竹工卡县|