Linux与macOS中pthread_cond_wait遇信号的行为探究
Linux与macOS下pthread_cond_wait被信号中断的行为差异
一、Linux手册的矛盾疑问
Linux的signal(7)手册末尾提到:被信号中断的pthread_cond_wait调用会返回EINTR错误(除非信号处理程序设置了sa_restart);但pthread_cond_wait(3)手册却明确说明该函数不会返回[EINTR]错误,这两处描述是否存在矛盾?
二、macOS下的测试情况
在macOS上无法找到signal(7)手册页,且pthread_cond_wait(2)手册未提及该函数会因EINTR失败。
测试代码
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <signal.h> #include <string.h> #include <unistd.h> #include <errno.h> void handle(int arg) {} void *task(void * arg) { pthread_cond_t cond; pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); pthread_mutex_lock(&mutex); errno = 0; int res = pthread_cond_wait(&cond, &mutex); printf("res = %d\n", res); printf("errno = %d\n", errno); return 0; } int main() { struct sigaction siga; memset(&siga, 0, sizeof(siga)); siga.sa_handler = handle; sigaction(SIGINT, &siga, NULL); pthread_t thread; pthread_create(&thread, 0, task, NULL); sleep(2); pthread_kill(thread, SIGINT); pthread_join(thread, NULL); printf("Ended\n"); return 0; }
输出结果
res = 0 errno = 260 Ended
输出中errno=260超出常规系统错误码范围,含义不明,需要明确macOS下该场景的实际行为。
三、实际行为解析
Linux平台
- 实际上,
pthread_cond_wait属于POSIX线程API,POSIX标准明确规定该函数不会返回EINTR,signal(7)的描述属于文档疏漏。 - Linux内核中,当
pthread_cond_wait被信号中断时,内核会自动重启该调用(即使未设置sa_restart),因此函数不会返回EINTR,行为完全符合pthread_cond_wait(3)手册的描述。 - 若信号处理程序设置了
sa_restart,行为无差异,因为该函数本身就会自动重启。
macOS平台
- macOS遵循POSIX标准,
pthread_cond_wait同样不会因信号中断返回错误码,测试中res=0也验证了这一点——函数正常返回,并未因信号中断失败。 - 测试中的
errno=260是无效值,原因是pthread系列函数不会设置errno,POSIX线程API的错误码直接通过返回值传递,读取errno的行为本身不符合规范,这个值是之前调用残留的随机值,没有实际意义。 - macOS的
pthread_cond_wait被信号中断后,会自动重新进入等待状态,直到条件变量被触发或其他合法错误发生。
内容的提问来源于stack exchange,提问作者Ernaldo
相关产品推荐
相关产品推荐

