You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 21:27:09