多线程编程中的信号处理与属性对象详解
1. 线程信号基础
每个线程都有自己的信号掩码,它决定了该线程会接受哪些信号。在进行多线程编程时,你只需关注线程信号掩码,无需考虑内核级信号掩码。你无法直接控制哪个线程会运行信号处理程序,只能通过设置信号掩码来影响。
作为程序员,你可以发送信号,甚至可以使用pthread_kill()直接将信号发送给程序内的单个线程。这些信号的行为与从外部发送的信号相同,并且保证会被发送到指定的线程。如果信号在发送时被屏蔽,它们会在该线程上排队等待,直到信号掩码被更改。
2. 异步安全问题
当你以为已经掌握了所有知识时,还有一个小细节需要注意,即异步安全(或信号安全)。例如,当你的线程调用malloc()时收到信号,而信号处理程序也调用了malloc(),由于大多数malloc()的实现需要锁定一些全局数据,可能会导致死锁。
因此,在使用库调用时,要查看手册页,了解其是否安全,是否有替代调用,或者是否需要自己进行处理。实际上,如果你听从建议,使用sigwait()而不是安装信号处理程序,这个问题通常不会很严重。大约有 80 个函数被定义为信号安全的(具体可参考供应商的文档)。
3. Solaris 中的信号处理实现
Solaris 线程库有一个特殊的绑定线程,负责处理所有信号传递问题。这个线程在启动时创建,并立即调用sigwait()函数,等待所有信号。当信号传递到进程时