信号默认处理动作及可重入函数

    下表列出了每种信号的默认处理动作(有些实现支持更多信号),以及支持此信号的系统。其中,SUS 列中的“*”表示此种信号定义为基本 POSIX.1 规范部分,“XSI”表示该信号定义为 XSI 扩展部分。而系统默认动作列中的“终止+core”表示在进程当前工作目录的 core 文件中复制了该进程的内存映像(大多数 UNIX 系统调试程序都使用 core 文件检查进程终止时的状态)。

    这里需要了解的是,在不同的实现中,core 文件的名字可能不同。例如,在 FreeBSD 8.0 中,core 文件名是 cmdname.core,其中 cmdname 是接收到信号的进程所执行的命令名;在 Mac  OS 10.6.8 中,core 文件名是 core.pid,其中 pid 是接收到信号的进程的 ID。这些系统允许经 sysctl 参数配置 core 文件名,如 Linux 3.2.0 可通过 /proc/sys/kernel/core_pattern 进行配置。多数实现在相应进程的工作目录中包含 core 文件项,但 Mac OS X 将所有 core 文件都放在 /cores 目录中。
    另外,在下列条件下不产生 core 文件:
    (1)进程是设置用户 ID 的,而且当前用户并非程序文件的所有者。
    (2)进程是设置组 ID 的,而且当前用户并非该程序文件的组所有者。
    (3)用户没有写当前工作目录的权限。
    (4)文件已存在,而且用户对该文件没有写权限(core 文件的权限通常是用户读/写)。
    (5)文件太大。

    进程捕捉到信号并对其进行处理时,它就会临时中断正在执行的正常指令序列,转而执行信号处理程序中的指令,在从信号处理程序返回后(如没有调用 exit 或 longjmp)又继续执行。但在信号处理程序中,不能判断捕捉到信号时进程执行到何处。如果进程正在执行 malloc,就可能会对进程造成破坏,因为 malloc 通常为它所分配的存储区维护一个链表,而插入执行信号处理程序时,进程可能正在更改此链表。再比如,若进程正在执行 getpwnam 这种将其结果存放在静态存储单元中的函数,其间插入执行信号处理程序,它又调用这样的函数,则返回给正常调用者的信息就可能会被覆盖。
    下表列出了 Single UNIX Specification 说明的在信号处理程序中保证调用安全的函数,它们是可重入的,并被称为异步信号安全的。此外,在信号处理操作期间,它们会阻塞任何会引起不一致的信号发送。

    不在该表中的大多数是不可重入的,因为(a)已知它们使用静态数据结构;(b)它们调用 malloc 或 free;(c)它们是标准 I/O 函数(标准 I/O 库的很多实现都以不可重入方式使用全局静态数据结构)。不过即使信号处理程序调用的是上表中的函数,但由于每个线程只有一个 errno 变量,所以信号处理程序可能会修改其原先值。因此,应当在信号处理程序中调用上图中的函数前保存 errno,调用后再恢复 errno。
    注意,上图中没有包含 longjmp 和 siglongjmp 之类的函数,因为主例程以非可重入方式正在更新一个数据结构时可能产生信号。如果不是从信号处理程序返回而是调用 siglongjmp,那么该数据结构可能是部分更新的。如果要做到更新全部数据结构,而同时要捕捉某些信号,而这些信号的处理程序又会引起执行 siglongjmp,则在更新时要阻塞此类信号。

猜你喜欢

转载自aisxyz.iteye.com/blog/2394900