<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

          linux內核中的信號機制--從用戶層到內核層

          作者: 時間:2016-11-22 來源:網絡 收藏
          Kernel version:2.6.14

          CPU architecture:ARM920T

          本文引用地址:http://www.ex-cimer.com/article/201611/320007.htm

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


          1.簡介

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

          2.signal()

          signal()的函數原型如下:

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

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

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

          signal()通過系統(tǒng)調用sys_signal()為一個指定的信號設置用戶態(tài)處理函數。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()的第一個參數指定,信號處理函數的地址由第二個參數指定。sys_signal()根據這兩個參數設置一個k_sigaction結構,然后調用do_sigaction(),該函數的定義我們會在后面具體講解。

          2.sigaction()

          sigaction()的函數原型如下:

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

          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結構中,這里是對整個數據結構進行復制
          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結構復制到進程的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結構復制到進程的sighand->action中
          58. sigdelsetmask(&k->sa.sa_mask,
          59. sigmask(SIGKILL)|sigmask(SIGSTOP));
          60. }
          61. spin_unlock_irq(¤tt->sighand->siglock);
          62. return0;
          63. }



          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();