C++11起应优先使用std::this_thread::sleep_for()和sleep_until(),需配合和,传入std::chrono持续时间类型;避免POSIX sleep/usleep及Windows Sleep()等非标准函数,确保跨平台与类型安全。

sleep_for 和 sleep_until 是 C++11 起的标准做法
不要用 sleep()、usleep() 这类 POSIX 函数,它们不是 C++ 标准,跨平台编译会失败(比如在 Windows MSVC 下直接报错 undefined reference)。C++11 引入了 std::this_thread::sleep_for() 和 std::this_thread::sleep_until(),依赖 和 头文件,可移植、类型安全。
常见错误是传错时间单位:必须用 std::chrono 的持续时间类型(如 std::chrono::seconds、std::chrono::milliseconds),不能直接传整数毫秒。
- 延时 500 毫秒:
std::this_thread::sleep_for(std::chrono::milliseconds(500)) - 延时 2 秒:
std::this_thread::sleep_for(std::chrono::seconds(2)) - 避免写成
sleep_for(500)—— 编译不过
Windows 下 _sleep() 和 Sleep() 容易混淆
Windows SDK 提供两个相似函数:_sleep()(来自 ?错,它实际在 ,已废弃且仅旧 MS-DOS 兼容环境支持)和真正可用的 Sleep()(注意首字母大写,参数单位是毫秒,需包含 )。
典型陷阱:
立即学习“C++免费学习笔记(深入)”;
-
Sleep(1000)延时 1 秒 —— 正确 -
sleep(1000)(小写)在 Windows 下不声明,链接时报错LNK2019: unresolved external symbol sleep -
_sleep(1000)在现代 Visual Studio 中找不到定义,编译失败
/* Windows-only, not portable */ #includeint main() { Sleep(1500); // 暂停 1.5 秒 return 0; }
Linux/macOS 下 nanosleep() 比 usleep() 更可靠
usleep(500000) 看似能休眠 500ms,但它已被标记为 obsolete(POSIX.1-2008 废弃),且某些系统上精度差、易被信号中断后提前返回。推荐用 nanosleep(),它支持纳秒级、可重入、中断后能续休。
关键点:
- 参数是
struct timespec,不是毫秒整数 - 必须检查返回值:若返回 -1 且
errno == EINTR,说明被信号打断,需手动重试 - 别漏掉
#include和#include
/* Linux/macOS 推荐(非 C++ 标准,但比 usleep 稳定) */ #include#include void safe_nanosleep(long ms) { struct timespec ts = {ms / 1000, (ms % 1000) * 1000000}; while (nanosleep(&ts, &ts) == -1 && errno == EINTR); }
sleep_for 在循环中卡死?小心 std::chrono::steady_clock 偏移
如果用 sleep_for() 写定时循环(比如每秒打印一次),但发现间隔越来越不准,可能是因为用了 system_clock 或没考虑线程调度延迟。正确做法是基于 steady_clock 计算下次唤醒时间,而不是固定间隔调用 sleep_for()。
例如,想严格每 1000ms 执行一次任务,应记录上次执行时间,下一次目标时间为 last + 1s,再用 sleep_until() 补齐偏差。
- 错误写法:
while(true) { do_work(); sleep_for(1s); }→ 实际间隔 = 执行耗时 + 1s - 正确写法:
auto next = steady_clock::now() + 1s; while(true) { do_work(); sleep_until(next); next += 1s; } - 尤其在负载高或
do_work()耗时波动大时,后者才能维持稳定周期
C++ 延时看似简单,但跨平台、精度控制、中断恢复、循环节拍这四点,任一处理不当都会导致行为意外。标准库的 sleep_for 是首选,但得配对用对 chrono 类型;平台特有函数只应在明确限定环境时使用,并做好条件编译。











