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

nanosleep调用后errno被设为ETIMEDOUT,POSIX手册未提及该错误

nanosleep调用后errno被设为ETIMEDOUT的疑问

每次调用nanosleep时,errno都会被设置为ETIMEDOUT(错误码60),这很奇怪——因为POSIX的nanosleep手册里并没有把ETIMEDOUT列为可能出现的错误。

这是个bug,还是我忽略了什么细节?

测试代码

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>

#define ONE_SC 1000000000
#define ONE_MS 1000000

int main() {
    struct timespec req = {ONE_MS / ONE_SC, ONE_MS % ONE_SC};
    struct timespec rem;

    printf("errno: %s (%d)\n", strerror(errno), errno);
    int rv = nanosleep(&req, &rem);
    printf("errno: %s (%d)\n", strerror(errno), errno);
    printf("rv: %d\n", rv);

    return 0;
}

代码输出

errno: Undefined error: 0 (0)
errno: Operation timed out (60)
rv: 0

运行环境

  • M1 Pro ARM MacBook
  • gcc版本:gcc-14 (Homebrew GCC 14.2.0_1) 14.2.0

问题解答

核心点在于:只有系统调用返回-1(失败)时,errno的值才是有效的。你的测试里nanosleep返回了0,说明睡眠正常完成,此时errno的数值完全是无意义的——POSIX标准并没有要求成功的系统调用必须重置errno,它可能保留之前的残留值,也可能被底层实现的某些操作意外修改。

根据POSIX规范,nanosleep仅在两种场景下返回错误并设置errno:

  • EINTR:睡眠过程被信号中断
  • EINVAL:传入的睡眠时间参数无效(比如纳秒部分不在0~999999999范围内)

你看到的ETIMEDOUT,应该是macOS底层实现nanosleep时,内部用到的某些机制(比如更底层的定时器调用)留下的痕迹,但因为最终睡眠成功完成,所以nanosleep返回了0,这个errno值不代表nanosleep本身出错。

这不是bug,完全符合POSIX标准的定义。正确的做法是:只在系统调用返回-1时,才去检查errno,成功调用时直接忽略errno即可。

内容的提问来源于stack exchange,提问作者suuniqo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:21:10