fork和exec调用之后,打开的文件描述符将会保留下来。
信号就是软件中断,它提供了一种处理异步时间的方法。
每个信号都有一个名字,以SIG开头。在头文件<signal.h>中定义了各种信号,通常来说信号是与体系结构相关的,也就是不通的CPU架构定义的信号不同。
不存在编号为0的信号。
产生信号的条件:
- 当用户按某些终端键时,引发终端产生信号。
- 硬件异常产生信号:如除数为0、无效的内存引用等。
- 系统调用kill(2)函数将信号发送给另一个进程或进程组。
- 用户可用kill(1)命令将信号发送给其他进程。
- 当检测到某种软件条件已发生,并应将其通知有关进程时也产生信号。
信号发生时,处理信号的三种方式为:忽略此信号、捕捉信号和执行系统默认动作。
SIGKILL和SIGSTOP不能忽略也不能捕捉。
UNIX信号机制接口函数:
#include <signla.h>
void (*signal(int signo, void (*func)(int)))(int);
若成功则返回信号以前的处理配置,出错则返回SIG_ERR。
关于该函数的解释可参考:
signal函数的返回地址实际上就是func函数的地址。
signo就是<signal.h>中定义的以SIG开头各种信号编号,func是常量SIG_IGN、SIG_DFL或接到此信号后要调用的函数的地址。func又称为信号处理程序或信号捕捉函数。
当执行一个程序时,所有信号的状态都是系统默认或忽略的。
当fork一个进程时,子进程会继承父进程的信号处理方式。
信号的不可靠:信号可能会丢失,也就是一个信号发生了,但进程却可能不知道这一点。这是早起UNIX版本中的问题。该系统调用返回出错,其errno被设置为EINTR。
中断的系统调用
早期UNIX系统的一个特性是:如果进程在执行一个低速系统调用而阻塞期间捕捉到一个信号,则该系统调用就被中断不再继续执行。注意此处被中断的是内核中执行的系统调用。
为了支持这种特性,系统调用被分为两类:低速系统调用和其他调用。
低速系统调用是可能会使进程永远阻塞的一类系统调用,包括:
- 在读某些类型的文件(管道、终端设备以及网络设备)时,如果数据并不存在则可能会使调用者永远阻塞。
- 在写这些类型的文件时,如果不能立即接受这些数据,则也可能会使调用者永远阻塞。
- 打开某些类型文件,在某种条件发生之前也可能会使调用者阻塞(如打开终端设备,它要等待直到所连接的调制解调器应答了电话)。
- pause和wait函数。
- 某些ioctl操作
- 某些进程间通信函数。
可重入函数
所谓可重入是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错。
未完待续。。。。