信号能够理解成一种软件中断。他提供了一种异步处理事件的方式。每一个信号都有一个与之对应的信号名,这些信号名都带有SIG前缀,如:SIGABRT,SIGALARM。头文件signal.h 中定义了全部的信号名,他们值为正整数常量。事实上,实现将个别信号定义在不一样的头文件中,只不过这些头文件又被包含在了signal.h中;这是由于内核不可能去包含应用于用户级别程序的头文件!所以,当用户程序与内核同时须要某信息的定义时,一般的作法是把这个定义放到内核头文件中,而后在用户头文件中包含这个内核头文件。安全
unix系统信号列表:数据结构
当信号列表中的默认action为“terminal+core”时,他意味着进程的内存映像会留在进程目录下的core文件中。core文件能够帮助大多数UNIX系统调试者来检查进程终止时的状态。可是,若是 a)进程设置了set-user-ID并且当前用户不是进程文件的拥有者;或者 b)进程设置了 set-group-ID 并且当前用户不是进程文件的用户组拥有者;或者 c) 当前用户下该用户没有写入权;或者d) 此文件已存在并且当前用户没有写入权;或者e)文件太大时core文件不会被建立。多线程
程序启动异步
当一个程序被执行的时候,全部的信号的装填要么是默认方式处理要么是忽略信号。一般,信号被设置为它们的默认处理方法,除非调用exec的进程忽略了这个信号。详细来讲exec函数会将调用exec进程捕获的信号的状态更改成信号的默认处理方式而保留其余信号的处理方式,由于exec执行的新程序中不包含捕获信号的函数地址,因此这些处理方式在新程序中是无心义的。async
进程建立函数
当一个进程调用fork时,子进程继承父进程的信号处理方式。在这里,子进程是由父进程的内存镜像的副本开始的,所以信号捕获函数的地址是有意义的。spa
可重入函数线程
当一个信号一个进程的信号处理函数捕获,此进程的正常指令执行顺序会被此信号处理短暂的中断,处理完信号后进程从以前被中断的地方继续执行。可是在信号处理函数中,咱们是没法识别出当信号被捕获是进程执行到了哪一步。若是当收到信号时进程正在经过malloc从堆上分配一块额外的内存时,咱们应该怎么办呢,在信号处理函数中调用malloc吗?亦或是当收到某个信号时咱们正在调用某个函数,好比getpwnam,这个函数将他的返回值存储在一个静态区域,这种状况下咱们应该在信号处理函数中调用一样的函数吗?在上面malloc的情景中那样作会对进程产生灾难性的后果,由于malloc一般包含一个它全部分配过的区域的连接表,也许当时它正处于更新这个连接表的状态中。在getpwnam的情境下,存储在静态区的getpwnam的返回值会被信号处理函数中的调用结果重写!unix
所以, The Single UNIX Specification 要求信号处理函数中的函数调用必须是安全的,便可重入的(Reentrant functions)。这些函数被 The Single Unix Specification称为异步信号安全函数(async-signal safe)。除了可重入,他们会在函数运行期间阻塞任何会破坏连续性的信号的下达。异步信号安全函数列表以下:调试
一些函数不被称为异步信号安全的缘由大体以下:
大多数标准I/O库的实现使用了静态数据结构,他们都不是可重入函数。须要特别注意的一点是:即便咱们在信号处理函数中使用异步信号安全的函数,每一个线程下也仅仅只有一个errno变量(在多线程环境下,多个线程共享进程地址空间。每一个线程须要它本身的errno副本以阻止线程间的相互干扰),而咱们可能会潜在的修改掉errno的值。所以,有个通则:在信号处理函数中调用异步信号安全函数前,应当保存errno。