- 1、本文档共17页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
信号的传递_徐波
信号的传递 徐波 Embedded System Lab 2014 信号传递 信号传递有两个阶段? 信号产生:内核更新目标进程的数据结构以表示一个新信号已被发送; 信号传递:内核强迫目标进程通过以下方式对信号做出反应:或改变目标进程的执行状态,或开始执行一个特定的信号处理程序,或者两者都是。 已经产生但还没有传递的信号称为挂起信号 一、信号的传递-引言 假定内核已经注意到一个信号的到来,并调用相应的函数为接收此信号的进程准备描述符。但是万一这个进程在那一刻并不在CPU上运行,内核就延迟传递信号的任务。那么我们现在就转向另一个主题,即为确保进程的挂起信号得到处理内核所执行的操作。 二、检查信号队列的时间 内核何时检查信号队列? 内核在允许进程恢复用户态下的执行之前,会检查进程TIF_SIGPENDING标志的值。(该标志表示进程是否有非阻塞的挂起信号,1为真) 每当内核处理完一个中断或异常时,就检查是否存在挂起的信号。 三、处理挂起信号 如何处理非阻塞的挂起信号量? 为了处理非阻塞的挂起信号,内核调用do_signal()函数进行处理; 阻塞信号:如果一个信号被设置为阻塞,那么当信号产生的时候,它会与正常的信号一样被传递给进程,但是只有进程解除对信号阻塞时才会被处理。 挂起信号:已经生成但是还未被传递的信号。 挂起信号-略讲 任何时候,一个进程仅存在给定类型的一个挂起信号,同一进程同种类型的其他信号不被排队,只被简单的丢弃。但是实时信号不同:同种类型的挂起信号可以有好几个 信号的挂起时间长度往往不可预知,原因在于: 信号通常只被current进程传递 进程可以选择阻塞某种信号。这种情况下,在取消阻塞之前进程将不接收这个信号 当进程执行一个信号处理程序函数时,通常屏蔽相应的信号,即自动阻塞这个信号直到处理程序结束。因此,所处理的信号的另一次出现不能中断信号处理程序 四、 do_signal()函数 do_signal()函数接受两个参数: regs:栈区的地址,存放当前进程在用户状态下寄存器的内容 oldset:变量的地址,假设存放阻塞信号的位掩码数组,如果没有必要保存位掩码数组,这它为NULL struct pt_regs *regs; //pt_regs结构,指向当前进程 内核态堆栈中保存的寄存器 sigset_t *oldset; //信号处理程序执行时要屏蔽的信号 二、检查信号队列的时间 时间:通常只是在CPU要返回到用户态时才被调用do_signal()函数。 四 do_signal()函数的核心 do_signal()函数核心: 循环调用dequeue_signal()函数,直到在私有挂起队列和共享挂起队列中都没有非阻塞的挂起信号 dequeue_signal()函数首先考虑私有挂起队列,并从最低编号开始,然后再共享队列;处理完后更新数据结构以表示信号不再挂起: 清位:currunt-pending.signal currunt-signal-shared_pending.signal 更新:调用recalc_sigpending()更新TIF_SIGPENDING do_signal()函数处理挂起信号 do_signal()函数处理挂起信号: 对于每一个挂起的信号,先检查当前进程是否被其他进程监控,如果是则让监控进程知道当前进程的信号处理; 把要处理信号的ka_sigsaction数据结构的地址赋给ka; 根据ka的内容可以执行三种操作:忽略信号、执行缺省操作或执行信号处理程序。 三种操作 1,显式的忽略信号 多数信号都可以使用这种方式进行处理。 2,执行系统默认的缺省操作,可以是: Terminate:进程被杀死 Dump:进程被杀死,且如果可能,创建包含进程上下文的可用于调试的core文件 Ignore:简单的忽略信号 Stop:进程被停止,状态置为TASK_STOPPED Continue:如果进程被挂起,则状态置为TASK_RUNNING。否则忽略该信号 3,捕获信号 为了执行用户希望的对某个事件的处理,可以由用户指定某个信号的处理函数。 五、三种操作 1、忽略信号。 if(ka-sa.sa_handler==SIG_IGN) { continue; } 此时程序将会忽略该信号,处理队列中的下一个信号 事实上,由于UNIX的历史原因,要想不产生僵尸进程还有另外一种办法:父进程调用sigaction将SIGCHLD的处理动作置为SIG_IGN,这样fork出来的子进程在终止时会自动清理掉,不会产生僵尸进程,
文档评论(0)