微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > linux内核中的信号机制--信号发送

linux内核中的信号机制--信号发送

时间:11-22 来源:互联网 点击:

  1. GAINwhenlowonmemorywejust
  2. makesureatleastonesignalgetsdeliveredanddont
  3. passontheinfostruct.*/
  4. q=__sigqueue_alloc(t,GFP_ATOMIC,(sig
  5. ((unsignedlong)info<2||
  6. info->si_code>=0)));//分配sigqueue结构
  7. if(q){//如果成功分配到sigqueue结构,就把它添加到队列中,并对其初始化
  8. list_add_tail(&q->list,&signals->list);
  9. switch((unsignedlong)info){
  10. case0:
  11. q->info.si_signo=sig;
  12. q->info.si_errno=0;
  13. q->info.si_code=SI_USER;
  14. q->info.si_pid=current->pid;
  15. q->info.si_uid=current->uid;
  16. break;
  17. case1:
  18. q->info.si_signo=sig;
  19. q->info.si_errno=0;
  20. q->info.si_code=SI_KERNEL;
  21. q->info.si_pid=0;
  22. q->info.si_uid=0;
  23. break;
  24. default:
  25. copy_siginfo(&q->info,info);//拷贝sigqueue结构
  26. break;
  27. }
  28. }else{
  29. if(sig>=SIGRTMIN&&info&&(unsignedlong)info!=1
  30. &&info->si_code!=SI_USER)
  31. /*
  32. *Queueoverflow,abort.Wemayabortifthesignalwasrt
  33. *andsentbyuserusingsomethingotherthankill().
  34. */
  35. return-EAGAIN;
  36. if(((unsignedlong)info>1)&&(info->si_code==SI_TIMER))
  37. /*
  38. *Setupareturntoindicatethatwedropped
  39. *thesignal.
  40. */
  41. ret=info->si_sys_private;
  42. }
  43. out_set:
  44. sigaddset(&signals->signal,sig);//设置信号位图
  45. returnret;
  46. }

从上面的分析可以看出,我们看到信号被添加到信号队列之后,会调用signal_wake_up()唤醒这个进程,signal_wake_up()(kernel/signal.c)的定义如下:

[plain]view plaincopyprint?

  1. /*
  2. *Tellaprocessthatithasanewactivesignal..
  3. *
  4. *NOTE!werelyonthepreviousspin_lockto
  5. *lockinterruptsforus!Wecanonlybecalledwith
  6. *"siglock"held,andthelocalinterruptmust
  7. *havebeendisabledwhenthatgotacquired!
  8. *
  9. *Noneedtosetneed_reschedsincesignaleventpassing
  10. *goesthrough->blocked
  11. */
  12. voidsignal_wake_up(structtask_struct*t,intresume)
  13. {
  14. unsignedintmask;
  15. set_tsk_thread_flag(t,TIF_SIGPENDING);//为进程设置TIF_SIGPENDING标志
  16. /*
  17. *ForSIGKILL,wewanttowakeitupinthestopped/tracedcase.
  18. *Wedontcheckt->stateherebecausethereisaracewithit
  19. *executinganotherprocessorandjustnowenteringstoppedstate.
  20. *Byusingwake_up_state,weensuretheprocesswillwakeupand
  21. *handleitsdeathsignal.
  22. */
  23. mask=TASK_INTERRUPTIBLE;
  24. if(resume)
  25. mask|=TASK_STOPPED|TASK_TRACED;
  26. if(!wake_up_state(t,mask))
  27. kick_process(t);
  28. }

signal_wake_up()首先为进程设置TIF_SIGPENDING标志,说明该进程有延迟的信号要等待处理。然后再调用wake_up_state()唤醒目标进程,如果目标进程在其他的CPU上运行,wake_up_state()将返回0,此时调用kick_process()向该CPU发送一个处理器间中断。当中断返回前戏,会为当前进程处理延迟的信号。

此后当该进程被调度时,在进程返回用户空间前,会调用do_notify_resume()处理该进程的信号。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top