昨天和同事在讨论安卓 ANR 的 SIGQUIT 信号处理时,有以下一些疑惑:

  • blocked signal 是什么意思,有什么意义,是针对进程的还是线程的
  • pthread_sigmask 是针对当前线程还是进程的
  • 关于 sigwait 的线程,sigwait 等待的 signal 是 blocked 还是 unblocked,或者都可以
  • 如何一个 signal handler 和 sigwait 都可以处理一个 signal,那谁先接收到该信号

接下来每个小节会按顺序说明这几个问题。

因为 blocked 和 pending 翻译起来有点别扭,所以相关专业词汇就直接用英文描述了。

# blocked signal

blocked signal 简单理解就是被中断的信号。不允许这些信号被信号处理器处理。

blocked signal 是针对线程的(以线程为对象)。

其作用在于防止某些线程处理特定信号。

其意义有两个:

  • 完成开发者需求:对线程手动设置了 signal mask,那么线程不会这些信号,防止错误发生。
  • 操作系统的机制:signal handler 处理信号 A 时,信号 A 会被操作系统设置为 blocked signal,即 signal handler 在处理特定信号时,不会处理相同类别的信号。当 signal handler 处理完信号 A 后,信号 A 会还原为 unblocked signal(以上仅针对同一个线程。一个线程的 signal handler 在处理信号 A 时,另一个线程也可以使用上述的 signal handler 去处理信号 A)。

# pthread_sigmask 是针对当前线程还是进程的

针对线程的,哪个线程调用 pthread_sigmask,哪个线程的 signal mask 会对应改变。

# sigwait 等待的 signal 是 blocked 还是 unblocked,或者都可以

都可以。根据官方文档,sigwait 是同步的,当 sigwait 对应的线程接收到处于 pending 状态的 signal,sigwait 返回对应的信号。这里没说处于 pending 状态的 signal 是 blocked 或者 unblocked(即线程的 sigmask 是否包含该信号),通过实验证明,blocked 和 unblocked 都可以。

# 如何一个 signal handler 和 sigwait 都处理同一个 signal,那谁会接收到该信号

根据实验表明,sigwait 会接收到该 signal,signal handler 不会被执行。

另外,如果 signal handler 等待 SIGINT 信号,而 sigwait 等待 SIGQUIT 信号,在发送 SIGINT 后,该线程仍处于 sigwait 的同步等待状态,signal handler 无法执行。