17-总结
22.14 总结
某些信号会引发进程创建一个核心转储文件,并终止进程。核心转储所包含的信息可供调试器检查进程终止时的状态。默认情况下,对核心转储文件的命名为core,但Linux提供了/proc/sys/kernel/core_pattern文件来控制对核心转储文件的命名。
信号的产生方式既可以是异步的,也可以是同步的。当由内核或者另一进程发送信号给进程时,信号可能是异步产生的。进程无法精确预测异步产生信号的传递时间。(文中曾指出,异步信号通常会在接收进程第二次从内核态切换到用户态时进行传递。)因进程自身执行代码而直接产生的信号则属于是同步产生的,例如,执行了一个引发硬件异常的指令,或者去调用raise()。同步生成的信号,其传递可以精确预测(立即传递)。
实时信号是POSIX对原始信号模型的扩展,不同之处包括对实时信号进行队列化管理,具有特定的传递顺序,并且还可以伴随少量数据一同发送。设计实时信号,意在供应用程序自定义使用。实时信号的发送使用sigqueue()系统调用,并且还向信号处理器函数提供了一个附加参数(siginfo_t结构),以便其获得信号的伴随数据,以及发送进程的进程ID和实际用户ID。
sigsuspend()系统调用在自动修改进程信号掩码的同时,还将挂起进程的执行直到信号到达,且二者属于同一原子操作。为了避免执行上述功能时出现竞态条件,确保sigsuspend()的原子性至关重要。
可以使用sigwaitinfo()和sigtimedwait()来同步等待一个信号。这省去了对信号处理器的设计和编码工作。对于以等待信号的传递为唯一目的的程序而言,使用信号处理器纯属多此一举。
像sigwaitinfo()和sigtimedwait()一样,可以使用Linux特有的signalfd()系统调用来同步等待一个信号。这一接口的独特之处在于可以通过文件描述符来读取信号。还可以使用select()、poll()和epoll来对其进行监控。
尽管可以将信号视为IPC的方式之一,但诸多制约因素令其常常无法胜任这一目的,其中包括信号的异步本质、不对信号进行排队处理的事实,以及较低的传递带宽。信号更为常见的应用场景是用于进程同步,或是各种其他目的(比如,事件通知、作业控制以及定时器到期)。
信号的基本概念虽然简单,但因为涉及的细节很多,所以对其讨论用去了3章的篇幅。信号在系统调用API的各部分中都扮演着重要角色,后面几章还将重温对信号的使用。此外,还有各种信号相关的函数是针对线程的(比如,pthread_kill()和 pthread_sigmask()),将延后至33.2节进行讨论。
更多信息
参见20.15节所列的信息来源。