您的位置 首页 观点

linux内核中的信号机制–从用户层到内核层

Kernelversion:2614CPUarchitecture:ARM920TAuthor:ce123(http:blogcsdnnetce123)1简介如果进程要处理某一信号,那么要在进

Kernel version:2.6.14

CPU architecture:ARM920T

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

1.简介

假如进程要处理某一信号,那么要在进程中注册该信号。注册信号首要用来确认信号值及进程针对该信号值的动作之间的映射联系,即进程即将处理哪个进程和该信号被传递给进程时,将履行何种操作。首要有两个函数完成信号的注册: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);

但这种格局在不同的体系中有不同的类型界说,所以要运用这种格局,最好仍是参阅一下手册。在调用中,参数signum指出要设置处理办法的信号。第二个参数handler是一个处理函数,或许是

  • SIG_IGN:疏忽参数signum所指的信号。
  • SIG_DFL:康复参数signum所指信号的处理办法为默认值。

传递给信号处理例程的整数参数是信号值,这样能够使得一个信号处理例程处理多个信号。体系调用signal()回来值是指定信号signum前一次的处理例程或许错误时回来错误代码SIG_ERR。

signal()经过体系调用sys_signal()为一个指定的信号设置用户态处理函数。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()对应的体系调用为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=&currentt->sighand->action[sig-1];
  8. spin_lock_irq(&currentt->sighand->siglock);
  9. if(signal_pending(current)){
  10. /*
  11. *Iftheremightbeafatalsignalpendingonmultiple
  12. *threads,makesurewetakeitbeforechangingtheaction.
  13. */
  14. spin_unlock_irq(&currentt->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(&current->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(&currentt->sighand->siglock);
  62. return0;
  63. }

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/guandian/262420.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部