将捕获到的已取消屏蔽的信号传送到等待条件变量的线程时,线程将从虚假唤醒的信号处理程序中返回。 虚假唤醒是指不是由其他线程中的条件信号调用导致的唤醒。在这种情况下,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。