`
luckyclouds
  • 浏览: 111435 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Linux 信号signal处理机制 二

阅读更多
二、信 号 机 制

        上 一节中介绍了信号的基本概念,在这一节中,我们将介绍内核如何实现信号机制。即内核如何向一个进程发送信号、进程如何接收一个信号、进程怎样控制自己对信 号的反应、内核在什么时机处理和怎样处理进程收到的信号。还要介绍一下setjmp和longjmp在信号中起到的作用。

        1、内核对信号的基本处理方法

        内 核给一个进程发送软中断信号的方法,是在进程所在的进程表项的信号域设置对应于该信号的位。这里要补充的是,如果信号发送给一个正在睡眠的进程,那么要看 该进程进入睡眠的优先级,如果进程睡眠在可被中断的优先级上,则唤醒进程;否则仅设置进程表中信号域相应的位,而不唤醒进程。这一点比较重要,因为进程检 查是否收到信号的时机是:一个进程在即将从内核态返回到用户态时;或者,在一个进程要进入或离开一个适当的低调度优先级睡眠状态时。

        内核处理一个进程收到的信号的时机是在一个进程从内核态返回用户态时。所以,当一个进程在内核态下运行时,软中断信号并不立即起作用,要等到将返回用户态时才处理。进程只有处理完信号才会返回用户态,进程在用户态下不会有未处理完的信号。

        内 核处理一个进程收到的软中断信号是在该进程的上下文中,因此,进程必须处于运行状态。前面介绍概念的时候讲过,处理信号有三种类型:进程接收到信号后退 出;进程忽略该信号;进程收到信号后执行用户设定用系统调用signal的函数。当进程接收到一个它忽略的信号时,进程丢弃该信号,就象没有收到该信号似 的继续运行。如果进程收到一个要捕捉的信号,那么进程从内核态返回用户态时执行用户定义的函数。而且执行用户定义的函数的方法很巧妙,内核是在用户栈上创 建一个新的层,该层中将返回地址的值设置成用户定义的处理函数的地址,这样进程从内核返回弹出栈顶时就返回到用户定义的函数处,从函数返回再弹出栈顶时, 才返回原先进入内核的地方。这样做的原因是用户定义的处理函数不能且不允许在内核态下执行(如果用户定义的函数在内核态下运行的话,用户就可以获得任何权 限)。

        在信号的处理方法中有几点特别要引起注意。第一,在一些系统中,当一个进程处理完中断信号返回用户态之前,内核清除用户区中设 定的对该信号的处理例程的地址,即下一次进程对该信号的处理方法又改为默认值,除非在下一次信号到来之前再次使用signal系统调用。这可能会使得进程 在调用signal之前又得到该信号而导致退出。在BSD中,内核不再清除该地址。但不清除该地址可能使得进程因为过多过快的得到某个信号而导致堆栈溢 出。为了避免出现上述情况。在BSD系统中,内核模拟了对硬件中断的处理方法,即在处理某个中断时,阻止接收新的该类中断。

        第二个要 引起注意的是,如果要捕捉的信号发生于进程正在一个系统调用中时,并且该进程睡眠在可中断的优先级上,这时该信号引起进程作一次longjmp,跳出睡眠 状态,返回用户态并执行信号处理例程。当从信号处理例程返回时,进程就象从系统调用返回一样,但返回了一个错误代码,指出该次系统调用曾经被中断。这要注 意的是,BSD系统中内核可以自动地重新开始系统调用。

        第三个要注意的地方:若进程睡眠在可中断的优先级上,则当它收到一个要忽略的信号时,该进程被唤醒,但不做longjmp,一般是继续睡眠。但用户感觉不到进程曾经被唤醒,而是象没有发生过该信号一样。

        第 四个要注意的地方:内核对子进程终止(SIGCLD)信号的处理方法与其他信号有所区别。当进程检查出收到了一个子进程终止的信号时,缺省情况下,该进程 就象没有收到该信号似的,如果父进程执行了系统调用wait,进程将从系统调用wait中醒来并返回wait调用,执行一系列wait调用的后续操作(找 出僵死的子进程,释放子进程的进程表项),然后从wait中返回。SIGCLD信号的作用是唤醒一个睡眠在可被中断优先级上的进程。如果该进程捕捉了这个 信号,就象普通信号处理一样转到处理例程。如果进程忽略该信号,那么系统调用wait的动作就有所不同,因为SIGCLD的作用仅仅是唤醒一个睡眠在可被 中断优先级上的进程,那么执行wait调用的父进程被唤醒继续执行wait调用的后续操作,然后等待其他的子进程。

        如果一个进程调用signal系统调用,并设置了SIGCLD的处理方法,并且该进程有子进程处于僵死状态,则内核将向该进程发一个SIGCLD信号。

        2、setjmp和longjmp的作用

        前面在介绍信号处理机制时,多次提到了setjmp和longjmp,但没有仔细说明它们的作用和实现方法。这里就此作一个简单的介绍。

        在 介绍信号的时候,我们看到多个地方要求进程在检查收到信号后,从原来的系统调用中直接返回,而不是等到该调用完成。这种进程突然改变其上下文的情况,就是 使用setjmp和longjmp的结果。setjmp将保存的上下文存入用户区,并继续在旧的上下文中执行。这就是说,进程执行一个系统调用,当因为资 源或其他原因要去睡眠时,内核为进程作了一次setjmp,如果在睡眠中被信号唤醒,进程不能再进入睡眠时,内核为进程调用longjmp,该操作是内核 为进程将原先setjmp调用保存在进程用户区的上下文恢复成现在的上下文,这样就使得进程可以恢复等待资源前的状态,而且内核为setjmp返回1,使 得进程知道该次系统调用失败。这就是它们的作用。
分享到:
评论

相关推荐

    Linux 信号signal处理机制.docx

    "Linux 信号signal处理机制" 本文详细介绍了Linux信号机制的基本概念、Linux对信号机制的大致实现方法、如何使用信号,以及有关信号的几个系统调用。信号机制是进程之间相互传递消息的一种方法,信号全称为软中断...

    Linux信号signal处理机制[参考].pdf

    Linux信号(Signal)处理机制是操作系统提供的一种进程间通信方式,用于进程间的异步通知。在Linux编程中,理解并掌握信号机制是非常关键的。本文将深入探讨信号的基本概念、处理方法、信号类型以及相关系统调用。 ...

    linux中的signal机制

    在Linux系统中,信号(Signal)机制是一种关键的进程间通信方式,用于处理各种系统事件,如用户输入中断、程序错误、硬件异常等。信号在Linux内核与应用程序之间搭建了一个桥梁,允许操作系统向进程发送特定的信息,...

    Linux信号(signal)机制.rar

    理解并熟练掌握Linux信号机制对于进行系统级编程至关重要。 信号是操作系统向进程发送的一种消息,它可能由内核生成,也可能由另一个进程产生。当进程接收到一个信号时,它可以选择忽略该信号,或者按照预设的行为...

    linux信号机制和signal

    ### Linux信号机制与Signal详解 #### 一、信号机制的基本概念 信号是Linux操作系统中用于进程间通信的重要机制之一,其本质上是一种软中断信号。它主要用于通知进程发生了异步事件,而不涉及具体的数据传递。在...

    Linux信号量处理

    Linux系统中的信号量处理涉及进程间通信的一种机制,允许一个进程在执行中被中断,响应另一个进程或终端发送的信号。信号提供了一种异步的软件中断方式,使得应用程序可以在接收到特定信号时,做出相应的处理。 ...

    Linux下Signal信号.pdf

    在Linux系统中,Signal机制允许进程处理各种事件,比如用户键入Ctrl+C结束程序,或者进程收到一个不可恢复的错误需要退出等。 ### Signal信号类型 Linux支持多种信号类型,包括标准信号和实时信号。标准信号是...

    Linux-signal

    ### Linux信号(signal)处理机制详解 #### 一、信号的基本概念 信号(signal),又被称为软中断信号,是一种用于进程间通信的重要机制。它允许进程在接收到特定的事件时能够采取相应的行动。信号的设计思想源自中断的...

    Linux的信号实现机制

    下面我们将深入探讨Linux信号机制的各个方面。 1. **信号定义与类型**:Linux系统定义了一系列预定义的信号,如SIGINT(中断,由Ctrl+C产生)、SIGTERM(正常终止请求)、SIGKILL(强制终止,无法被捕获或忽略)...

    linux信号的机制

    ### Linux信号机制详解 #### 一、信号的基本概念 在Linux操作系统中,信号(Signal)是一种重要的进程间通信(IPC, Inter-Process Communication)机制,主要用于通知进程发生了某些类型的异常事件或状态变化。...

    Linux信号机制的分析与研究

    ### Linux信号机制的分析与研究 #### 一、引言 在现代操作系统中,Linux以其稳定性和灵活性成为了服务器领域的首选操作系统之一。其中,信号机制作为Linux内核中的一个重要组成部分,对于实现进程间的通信和异常...

    第9章linux信号与定时器

    2. **signal**:用于设置指定信号的处理方式,但功能相对简单,不支持一些高级特性。 3. **kill**:向指定的进程发送信号。 4. **raise**:向当前进程发送信号。 5. **sigemptyset**:初始化信号集并清空。 6. **...

    Linux信号与信号处理文.pdf

    总的来说,Linux信号机制为进程间的交互提供了灵活的方式,通过设置信号处理函数,可以定制化程序对不同事件的响应。信号处理不仅可以用于进程间的通信,也可以用于内部程序控制,如异常处理、定时器等。了解和熟练...

    Linux信号编程课件与实验代码.rar

    Linux信号编程是操作系统领域的重要组成部分,特别是在开发服务器端软件或者进行系统级编程时,理解并掌握信号机制至关重要。本资源“Linux信号编程课件与实验代码.rar”提供了一个全面学习和实践Linux信号处理的...

    linux 信号使用示例

    总结来说,Linux信号机制提供了进程间通信的基础,它不仅能够帮助我们处理异常情况,还能够用于控制进程行为和协调进程间的同步。`signalWcg.c`和`signalWcgClient.c`的示例可能展示了如何创建信号处理器、发送和...

    Linux下C语言编程--信号处理函数.

    ### Linux下C语言编程——信号处理函数 #### 一、信号的基本概念与产生 在Linux系统中,**信号**是一种轻量级的进程间通信机制,用于通知接收进程某个特定事件的发生。它不仅可以由硬件异常(如除零错误)触发,也...

Global site tag (gtag.js) - Google Analytics