多线程编程指南

对信号执行的操作

本节介绍对信号执行的操作。

设置线程的信号掩码

将信号发送到特定线程

等待指定信号

在给定时间内等待指定的信号

设置线程的信号掩码

pthread_sigmask(3C) 对线程执行 sigprocmask(2) 对进程所执行的操作。pthread_sigmask() 可以设置 thread 的信号掩码。创建新的线程时,其初始掩码是从其创建者继承的。

在多线程进程中对 sigprocmask() 执行调用等效于对 pthread_sigmask() 执行调用。有关更多信息,请参见 sigprocmask(2) 手册页。

将信号发送到特定线程

pthread_kill(3C)kill(2) 的线程模拟。pthread_kill() 可以将信号发送到特定线程。发送到指定线程的信号不同于发送到进程的信号。将信号发送到进程时,信号可由该进程中的任何线程来处理。通过 pthread_kill() 发送的信号只能由指定线程来处理。

可以使用 pthread_kill() 将信号仅发送到当前进程中的线程。由于 thread_t 类型的线程标识符的范围是本地,因此不能指定当前进程范围以外的线程。

通过目标线程接收信号时,调用的操作(处理程序 SIG_DFLSIG_IGN)通常为全局操作。如果将 SIGXXX 发送到线程,且 SIGXXX 的作用是中止进程,则目标线程接收信号时将中止整个进程。

等待指定信号

对于多线程程序,sigwait(2) 是可供使用的首选接口,因为 sigwait() 可以很好地处理异步生成的信号。

sigwait() 将导致调用线程等待,直到由其设置参数标识的任何信号被传送到该线程为止。线程等待的同时,系统将取消屏蔽由设置参数标识的信号,但调用返回时将恢复原始掩码。

由设置参数标识的所有信号必定会在所有线程(包括调用线程)上受到阻塞。否则,sigwait() 可能无法正常工作。

使用 sigwait() 将线程与异步信号分离。创建一个侦听异步信号的线程时,可同时创建其他线程来阻塞为此进程设置的任何异步信号。

从 Solaris 2.5 发行版开始,可以使用 sigwait() 的两个版本:Solaris 2.5 版本和 POSIX 标准版本。新的应用程序和新的库应该使用 POSIX 标准接口,因为 Solaris 版本在未来的发行版中可能不可用。

以下示例显示了 sigwait() 的两个版本的语法:

#include <signal.h>



/* the Solaris 2.5 version*/

int sigwait(sigset_t *set);



/* the POSIX standard version */

int sigwait(const sigset_t *set, int *sig);

传送信号时,POSIX sigwait() 将清除暂挂信号,并将信号数字置于 sig 中。许多线程可以同时调用 sigwait(),但是针对每个接收的信号仅返回一个线程。

借助 sigwait(),可以同时处理异步信号。信号到达后,处理这类信号的线程将立即调用 sigwait() 并返回。通过确保所有线程(包括 sigwait() 的调用程序)都屏蔽异步信号,可确保信号仅由预期处理程序处理,且安全地进行处理。

通过始终屏蔽所有线程中的所有信号并在必要时调用 sigwait(),可以使应用程序中依赖于信号的线程的安全性大大提高。

通常,可以创建一个或多个为等待信号而调用 sigwait() 的线程。由于 sigwait() 甚至会检索屏蔽的信号,因此一定要阻塞所有其他线程中的重要信号,以便不会意外传送这些信号。

信号到达时,线程将从 sigwait() 返回,处理信号,并再次调用 sigwait() 以等待更多信号。信号处理线程并不限于使用异步信号安全函数。信号处理线程可采用通常的方式与其他线程同步。MT 接口安全级别定义了异步信号安全类别。


注 –

sigwait() 不能接收同步生成的信号。


在给定时间内等待指定的信号

sigtimedwait(3RT) 类似于 sigwait(2),但在指定的时间内没有收到信号时,sigtimedwait() 将失败并返回错误。