Ch 10 信号
信号提供了一种异步处理事件的方法
信号名:SIG开头 产生信号的条件:
- 终端键
- 硬件异常:除0,无效的内存引用(SIGSEGV)
- kill 函数可将任意信号发送给另一个进程或进程组
- 检测到某些软件条件已经发生,生产者消费者等
信号需要告诉内核,由内核来执行相应的操作
某信号出现的时候,可以告诉内核按下列方式处理:
- 忽略(SIGKILL和SIGSTOP除外)
- 捕捉信号:通知内核在某信号发生的时候调用一个用户函数
- 执行系统默认动作,大多数信号的默认动作都是终止
使用 signal 函数可以注册对应信号(用户自定义的也行)的回调函数
因为信号捕捉函数的地址很可能在所执行的新程序文件中已无意义。因此 exec 会将原先设置要捕捉的信号都更改为默认动作,其他信号的状态不变。
子进程继承其父进程的信号处理方式,因为子进程会复制父进程的内存空间,因此信号捕捉函数的地址在子进程是有意义的
在信号处理程序中调用一个非可重入函数,其结果是不可预知的
在一个信号产生的时候,内核通常在进程表中以某种形式设置一个标志(递送),在产生和递送的间隙,称信号是未决的
超级用户可将信号发送给任一进程,对于非超级用户而言,发送者的实际用户ID必须等于接收者的实际用户ID或有效用户ID
中断系统调用
如果进程在执行一个低速系统调用而阻塞期间捕捉到一个信号,则该系统调用就被中断不再继续执行,并返回出错。 例如:一个中断阻塞在读取用户输入上,但是用户已经离开终端。
多信号处理
进程可以选择阻塞信号递送的方式,每个进程都可以用设置信号屏蔽字的方式来防止内核递送信号(在解除之前该信号会保持未决状态),从而达到阻塞递送的目的
信号集
系统提供了一个能表示多个信号的数据结构:信号集。
信号的应用
进行进程间的同步
abort
使程序异常终止,要求捕捉 SIGABRT 的响应信号处理程序返回,而且不会返回到调用者。不能返回的唯一方法是它调用 exit,longjmp,siglongjmp。abort 并不会理会进程对此信号的阻塞和忽略。处理程序可以在终结前做一些清理工作