我想确切地了解异步信号处理程序在Linux上的执行情况.首先,我不清楚是否有which个线程执行信号处理程序.其次,我想知道让线程执行信号处理程序所遵循的步骤.
关于第一件事,我读了两种不同的、似乎相互矛盾的解释:
-
"Linux内核"(The Linux Kernel),安德烈·布劳威尔(Andries Brouwer),§5.2 "Receiving signals" states:
当信号到达时,进程被中断,当前寄存器被保存,信号处理程序被调用.当信号处理程序返回时,中断的活动将继续.
-
StackOverflow question "Dealing With Asynchronous Signals In Multi Threaded Program"让我觉得Linux的行为是like SCO Unix's:
当一个信号被传递到一个进程时,如果它被捕获,它将由一个线程处理,并且只有一个线程满足以下条件之一:
在sigwait(2)系统调用中阻塞的线程,其参数does包括捕获信号的类型.
一种线程,其信号掩码does not包括捕获信号的类型.
其他注意事项:
- 在sigwait(2)中阻塞的线程优先于未阻塞该信号类型的线程.
- 如果超过一个线程满足这些要求(可能有两个线程调用sigwait(2)),那么将 Select 其中一个线程.应用程序无法预测这种 Select .
- 如果没有符合条件的线程,信号将在进程级别保持"挂起",直到某个线程符合条件.
此外,"The Linux Signals Handling Model" by Moshe Bar states个"异步信号被传送到第一个发现没有阻塞信号的线程.",我的理解是,信号被传送到某个线程,其sigmask not包含该信号.
哪一个是正确的?
在第二个问题上,所选线程的堆栈和寄存器内容会发生什么情况?假设运行信号处理程序的线程T正在执行do_stuff()
函数.线程T的堆栈是否直接用于执行信号处理程序(即,信号蹦床的地址被压入T的堆栈,并且控制流转到信号处理程序)?或者,是否使用单独的堆栈?它怎麽工作?