信号

10 信号

10.1 简介

信号是软中断。很多比较重要的程序都需要处理信号。信号提供了一种处理异步事件的方法,如终端用户键入中断键,会通过信号机制停止一个程序,或及早终止管道汇总的下一个程序。

10.2 信号概念

每个信号都有一个名字。这些名字以SIG字符开头。不存在编号为0的信号Kill函数对信号编号0有特殊的应用。POSIX.1将此种信号编号值称为空信号。很多条件可以产生信号。

当用户按某些终端键时,引发终端产生的信号。
硬件异常产生信号:除数为0,无效的内存引用等。
进程调用kill函数可将任意信号发送给另一个进程或进程组。对此存在限制:*接收信号进程和发送信号进程的所有者必须相同,或发送信号进程的所有者必须是超级用户*。
当检测到某种软件条件已经发生,并应将其通知有关进程时也产生信号。

信号是异步事件的经典实例。产生信号的事件对进程而言是随机出现的。进程不能简单地测试一个变量来判断是否发生了一个信号,而是必须告诉内核,在此信号发生时,请执行下列操作。

在某个信号出现时,可以告诉内核按下列3种方式之一进行处理,称为信号处理和信号相关的动作。

忽略此信号。多数可以,但SIGKILL和SIGSTOP不能忽略。因为他们向内核和超级用户提供了使进程终止或停止的可靠方法。此外,某些硬件异常信号,也不能忽略,忽略后运行行为可能是未定义的。
捕捉信号
执行系统默认动作*。注意:大多数信号的系统默认动作是终止该进程。*

下列条件下不产生core文件:

进程是设置用户ID的,而且当前用户并非程序文件的所有者
进程是设置组ID的,而且当前用户并非改程序文件的组所有者
用户没有写当前工作目录的权限
文件已存在,而且用户对该文件设有写权限
文件太大。

10.3 函数signal

UNIX系统信号机制最简单的接口是signal函数。其中参数中指定函数地址时,则在信号发生时,调用该函数,称为处理捕捉该信号,即信号处理程序和信号捕捉函数。

10.4 不可靠的信号

早期UNIX中,信号是不可靠的。不可靠指:信号可能会丢失:一个信号发生了,但进程却可能一直不知道这一点。同时,进程对信号的控制能力也很差,它能捕捉信号或忽略它。有时用户希望通知内核阻塞某个信号:不要忽略该信号,在其发生时记住它,然后在进程做好了准备时在通知他。

后期,系统提供可靠的信号机制。

10.5 中段的系统调用

早期UNIX系统的一个特性:如果进程在执行一个低速系统调用而阻塞期间捕捉的一个信号,则该系统的调用就被中断,不在继续执行。该系统调用返回错误,其errno设置EINTR。在此,必须区分系统和函数。当捕捉到某个信号时,被中断的内核中执行的是系统调用

系统调用分为两类:低速系统调用和其他系统调用。低速系统调用是可能会使进程永远阻塞的一类系统调用,包括:

如果某些类型的文件(如读管道,终端设备和网络设备)的数据不存在,则读操作可能会使调用者永远阻塞
如果这些数据不能被相同的类型文件立即接受,则写操作可能会使调用者永远阻塞
在某些条件发生之前打开某些类型文件,可能会发生阻塞(如打开一个终端设备,需要先等待与之连接的调制解调器应答)
Pause函数(它是调用进程休眠直至捕捉到一个信号)和wait函数
某些ioctl操作
某些进程间通信函数。

在低速系统调用者,一个值得注意的例外是与磁盘I/O有关的系统调用。虽然读、写一个磁盘文件可能暂时阻塞调用者(在磁盘驱动程序将请求排入队列,然后在适当时间执行请求期间),大事除非发生硬件错误,I/O操作总会很快返回,并使调用者不再处于阻塞状态。

BSD引入自动重启动功能的理由:有时用户并不知道使用的输入输出设备是否是低速设备。

10.6 可重入函数

在信号处理程序中,保证调用安全的函数,是可重入的并被称为是异步信号安全的。除了可重入以外,在信号处理操作期间,他会阻塞任何会引起不一致的信号发送。

不可重入函数:已知他们使用静态数据结构;他们调用malloc和free;他们是标准I/O函数。

10.7 SIGGLD语义

对SIGCLD的早期处理方式:

如果进程明确地将该信号的配置设置为SIG_IGN,则调用进程的子进程将不产生僵死进程
果将SIGCLD的配置设置为捕捉,则内核立即检查是否有子进程准备好等待,如果是这样,则调用SIGCLD程序

10.8 可靠信号术语和语义

当造成信号的事件发生时,为进程产生一个信号(或向一个进程发送一个信号)。事件可以是硬件异常(如除以0),软件条件(如alarm定时器超时),终端产生的信号或调用kill函数。当一个信号产生时,内核通常在进程表中以某种形式设置一个标志。

当对信号采取了这种动作时,称进程递送了一个信号。在信号产生和递送之间的时间间隔内,称信号是未决的。

进程可以阻塞信号递送。POSIX.1允许系统递送信号一次或多次。如果有多个信号要递送给一个进程,则建议在其他信号之前递送与进程当前状态相关的信号。

每个进程都有一个信号屏蔽字,它规定了当前要阻塞递送到该进程的信号集。对于每种可能的信号,该屏蔽字中都有一位与之对应。对于某种信号,如果其对应位已设置,则当它是被阻塞的。进程可以调用sigprocmask来检测和更改其当前信号屏蔽字。

10.9 函数kill和raise

Kill函数将信号发送给进程和进程组。Raise函数则允许进程向自身发送信号。

10.10 函数alarm和pause

使用alarm函数可以设置一个定时器(闹钟时间),在将来的某个时刻该定时器会超时。当定时器超时时,产生SIGALRM信号。如果忽略或不捕捉此信号,则其默认动作是终止调用该alarm函数的进程。

Pause函数使调用进程挂起直至捕捉到一个信号。只有执行了一个信号处理程序并从其返回,pause才返回。在这种情况下,pause返回-1,errno设置为EINTR。

10.11 信号集

信号集,用来表示多个信号。一旦已经初始化了一个信号集,以后就可在该信号集中增,删特定的信号

10.12 函数sigprocmask

一个进程的信号屏蔽字规定了当前阻塞而不能传送给该进程的信号集。调用函数sigprocmask可以监测和更改,或同时进行检测和更改进程的信号屏蔽字。Sigprocmask仅为单线程进程定义的。处理多线程进程中信号的屏蔽使用另一个函数。

10.13 函数sigpending

Sigpending函数返回一信号集,对于调用进程而言,其中的各信号是阻塞不能递送的,因而也一定是当前未决的。

10.14 函数sigaction

Sigaction函数的功能是检查或修改(或检查并修改)与指定信号相关联的动作。

10.15 函数sigsetjmp和siglongjmp

Sigsetjmp和siglongjmp函数主要在信号处理过程中进行非局部转移时使用。

10.16 函数sigsuspend

Sigsuspend函数用于在原子操作中恢复信号屏蔽字,然后使进程休眠。

10.17 函数abort

Aboart函数功能:使程序异常终止。让进程捕捉SIGABRT的意图是:在进程终止之前由其执行所需的清理操作。

10.18 函数system

System函数可以用来执行信号处理。当用system运行另一个程序时,不应使父子进程两者都捕捉终端产生的两个信号:中断和退出。这两个信号只应发送给正在运行的程序:子进程。因为由system执行的命令可能是交互式命令,以及因为system的调用者在程序执行时放弃了控制,等待该执行程序的结束,所以system的调用者就不应该接收到这两个终端产生的信号。

10.19 函数sleep、nanosleep和clock_nanosleep

Sleep函数使调用程序被挂起直到满足下列两个条件之一:

已经过了seconds所指定的墙上时钟时间
调用进程捕获了一个信号从信号处理程序返回。

10.20 函数sigqueue

大部分UNIX系统不对信号排队,但在POSIX.1的实时扩展中,有些系统开始增加对信号排队的支持。

通常一个信号带有一个位信息:信号本身。除了对信号排队外,这些扩展允许应用程序在递交信号时传递更多的信息。这些信息嵌入在siginfo结构中。除了系统提供的信息,应用程序还可以向信号处理传递整数或者指向包含更多信息的缓冲区指针。

使用排队信号必须做以下几个操作:

使用sigaction函数安装信号处理程序时指定SA_AIGINFO标志。如果没有给出这个标志,信号会延迟,但信号是否进入队列要取决于具体实现。
在sigaction结构的sa_sigaction成员中(而不是通常的sa_handler字段)提供信号处理程序。实现可能允许用户使用sa_handler字段,但不能获取sigqueue函数发送出来的额外信息。
**使用sigqueue函数发送信号。**Sigqueue函数只能把信号发送给单个进程,可以使用value参数向信号处理程序传递整数和指针值,除此之外,sigqueue函数与kill函数类似。但信号不能被无限排队。

10.21 作业控制信号

POSIX.1认为有以下6个信号与作业控制有关:

SIGCHLD 子进程已停止或终止
SIGCONT 如果进程已停止,则使其继续运行
SIGSTOP 停止信号(不能被捕捉或忽略)
SIGTSTP 交互式停止信号
SIGTTIN 后台进程组成员读控制终端
SIGTTOU 后台进程组成员写控制终端

10.22 信号名和编号

信号编号和信号名之间存在映射。

  • 参考文献:Unix环境高级编程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值