10.2 信号的概念

每个信号都有一个名字。这些名字都以三个字符SIG开头。SIGABRT是夭折信号,当进程调用abort函数时产生这种信号。SIGALRM是闹钟信号,当由alarm函数设置的时间已经超过后产生此信号。V7有15种不同的信号,SVR4和4.3+BSD均有31种不同的信号。在头文件中,这些信号都被定义为正整数(信号编号)。没有一个信号其编号为0。在10.9节中将会看到kill函数,对信号编号0有特殊的应用。POSIX.1将此种信号编号值称为空信号。

很多条件可以产生一个信号:

  • 当用户按某些终端键时,产生信号。在终端上按DELETE键通常产生中断信号(SIGINT)。这是停止一个已失去控制程序的方法。(第11章将说明此信号可被映射为终端上的任一字符。)

  • 硬件异常产生信号:除数为0、无效的存储访问等等。这些条件通常由硬件检测到,并将其通知内核。然后内核为该条件发生时正在运行的进程产生适当的信号。对执行一个无效存储访问的进程产生一个SIGSEGV。

  • 进程用kill(2)函数可将信号发送给另一个进程或进程组。自然,有些限制:接收信号进程和发送信号进程的所有者必须相同,或发送信号进程的所有者必须是超级用户。

  • 用户可用kill(1)命令将信号发送给其他进程。此程序是kill函数的界面。常用此命令终止一个失控的后台进程。

  • 当检测到某种软件条件已经发生,并将其通知有关进程时也产生信号。这里并不是指硬件产生条件(如被0除),而是软件条件。例如SIGURG(在网络连接上传来非规定波特率的数据)、SIGPIPE(在管道的读进程已终止后一个进程写此管道),以及SIGALRM(进程所设置的闹钟时间已经超时)。信号是异步事件的经典实例。产生信号的事件对进程而言是随机出现的。进程不能只是测试一个变量(例如errno)来判别是否发生了一个信号,而是必须告诉内核“在此信号发生时,请...”。

你是否对多进程异步事件驱动引擎感兴趣?可以参考这篇详解Python实现多进程异步事件驱动引擎。想了解更多关于POSIX线程的信息?这篇文章会给你详细的解答。如果你对信号量、邮箱和消息队列事件等内容有兴趣,不妨看看这篇信号量邮箱和消息队列事件异步信号管道。关于WinSock的异步事件处理,这里有详细的介绍。

信号的世界真是奇妙无比,有没有觉得这个领域充满了惊喜和挑战?理解这些信号不仅能提升你的编程技能,还能帮助你更好地掌控程序的执行流程。