将捕获到的已取消屏蔽的信号传送到等待条件变量的线程时,线程将从虚假唤醒的信号处理程序中返回。 虚假唤醒是指不是由其他线程中的条件信号调用导致的唤醒。在这种情况下,Solaris 线程接口 cond_wait() 和 cond_timedwait() 将返回 EINTR,而 POSIX 线程接口 pthread_cond_wait() 和 pthread_cond_timedwait() 将返回 0。在所有情况下,从条件等待返回之前都将重新获取关联的互斥锁定。
重新获取关联的互斥锁定并不暗示线程在执行信号处理程序的同时,互斥处于锁定状态。未定义信号处理程序中的互斥状态。
由于在 Solaris 9 发行版之前的 Solaris 软件发行版中实现了 libthread,因而保证了在处于信号处理程序中时保留了互斥。依赖此原有行为的应用程序需要修改 Solaris 9 发行版以及后续发行版。
示例 5–4 将对处理程序清除加以说明。
int sig_catcher() { sigset_t set; void hdlr(); mutex_lock(&mut); sigemptyset(&set); sigaddset(&set, SIGINT); sigsetmask(SIG_UNBLOCK, &set, 0); if (cond_wait(&cond, &mut) == EINTR) { /* signal occurred and lock is held */ cleanup(); mutex_unlock(&mut); return(0); } normal_processing(); mutex_unlock(&mut); return(1); } void hdlr() { /* state of the lock is undefined */ ... }
假设 SIGINT 信号在进入 sig_catcher() 时在所有线程中受到阻塞。此外,还假设已通过调用 sigaction(2) 建立了 hdlr()(作为 SIGINT 信号的处理程序)。如果在线程处于 cond_wait() 中时将捕获到的已取消屏蔽的 SIGINT 信号实例传送到该线程,该线程将调用 hdlr()。然后,线程将返回到 cond_wait() 函数(如有必要,将在此处重新获取互斥锁定),并从 cond_wait() 返回 EINTR。
是否已针对 sigaction() 将 SA_RESTART 指定为标志在此处无影响。cond_wait(3C) 不是系统调用,也不会自动重新启动。如果在 cond_wait() 中阻塞线程时出现捕获的信号,则调用将始终返回 EINTR。