现在的位置: 首页 > 综合 > 正文

[glibc-manual]34.9 线程与信号处理

2013年09月13日 ⁄ 综合 ⁄ 共 1306字 ⁄ 字号 评论关闭

34.9 线程与信号处理

-- 函数: int pthread_sigmask (int HOW, const sigset_t *NEWMASK, sigset_t *OLDMASK)
pthread_sigmask 依照 HOW 和 NEWMASK 的指示改变调用线程的信号掩码(signal mask)。如果 OLDMASK 不是 NULL,则之前的信号掩码将被保存在 OLDMASK 指向的位置。
参数 HOW 和 NEWMASK 的含义与 sigprocmask 的相同。如果 HOW 指定为 SIG_SETMASK 则线程的信号掩码被设置为 NEWMASK。如果 HOW 为 SIG_BLOCK 则 NEWMASK 指定的掩码将被加入当前线程的信号掩码中。如果 HOW 为 SIG_UNBLOCK 则 NEWMASK 中指定的信号将从当前信号掩码中移除。
回忆一下,信号掩码是各个线程独享的,但是经由 sigaction 设置的信号处理方式和信号句柄(signal handlers),则由进程中的所有线程共享。
pthread_sigmask 函数在成功时返回 0,错误时则返回如下错误码之一:
EINVAL
  HOW 不是 SIG_SETMASK, SIG_BLOCK 或 SIG_UNBLOCK 之一
EFALUT
  NEWASK 或 OLDMASK 指向非法地址。

-- 函数: int sigwait (const sigset_t *SET, int *SIG)
sigwait 会将当前线程挂起直到线程收到 SET 中指定的信号之一。随后它将收到信号的数量保存在 SIG 指向的变量中并返回线程执行。当调用 sigwait 时,SET 中的信号必须被阻塞而不是忽略。如果收到的信号有信号处理句柄,这个句柄不会被自动调用。
sigwait 是一个线程取消点(cancellation point)。它始终返回 0。

如果希望 sigwait 能可靠地工作,被等待的信号应该在所有线程中均被阻塞,而不仅仅是调用线程。否则,POSIX 信号语义无法保证调用 sigwait 的线程一定能够收到这个信号。最佳方法是,在创建任何线程之前阻塞这些信号,并保证在除调用 sigwait 之外的情况中不会取消阻塞。

LinuxThreads 中的信号处理与 POSIX 标准相去甚远。根据标准规定,“异步”(外部)信号的目标是整个进程(所有线程的集合),而进程将信号传递给某个特定的线程。收到信号的线程可能是任意一个当前没有阻塞该信号的线程。

在 LinuxThreads 实现中,每个线程均为一个具有单独 PID 的核心进程,因此外部线程总是发送到某个特定线程。例如,当另外一个线程在 sigwait 中阻塞时,它无法被这个信号唤醒。

LinuxThreads 中的 sigwait 实现在阻塞过程中为 SET 中的线程设置了傀儡句柄。因为信号句柄会在所有线程中共享,其它线程不可以自己为这些信号设置句柄;另一种方案是其它线程均阻塞这些信号(这始终是推荐的处理方法)。

译者注
1、新的 NPTL 较之 LT,在 Signal Handling 方面有了很大改进。取消了 manager thread,引入了真正的基于进程的(而不是基于单独线程的)信号模型。
2、仍然不是我要的东西。。POSIX Signals 的介绍难道在 libc6 的 info 中没有么?

【上篇】
【下篇】

抱歉!评论已关闭.