在 Linux C 编程中,让程序暂停(睡眠)一段最常用、最标准的方法是使用 sleep() 函数,还有更精确的 nanosleep() 和 POSIX 定时器 timer_create() 等方法。

(图片来源网络,侵删)
标准方法:sleep() 函数
这是最简单、最直观的方法,适用于大多数需要简单延时的场景。
函数原型
sleep() 函数在 unistd.h 头文件中声明。
#include <unistd.h> unsigned int sleep(unsigned int seconds);
参数和返回值
- 参数
seconds: 你希望程序暂停的秒数,是一个无符号整型。 - 返回值:
- 如果成功,
sleep()会让进程暂停指定的秒数,然后返回 0。 - 如果在睡眠期间被信号中断(用户按下了
Ctrl+C),它会立即返回,并返回 剩余的秒数(即seconds - 实际睡眠时间)。
- 如果成功,
示例代码
下面的例子会打印一条消息,然后睡眠 5 秒,之后再打印另一条消息。
#include <stdio.h>
#include <unistd.h> // 必须包含此头文件
int main() {
printf("程序开始运行...\n");
printf("准备睡眠 5 秒...\n");
// 调用 sleep 函数,暂停 5 秒
unsigned int remaining_seconds = sleep(5);
printf("睡眠结束!\n");
if (remaining_seconds > 0) {
printf("睡眠被中断,还剩 %u 秒,\n", remaining_seconds);
}
printf("程序继续运行,\n");
return 0;
}
如何编译和运行
- 将代码保存为
sleep_example.c。 - 打开终端,使用
gcc进行编译:gcc sleep_example.c -o sleep_example
- 运行生成的可执行文件:
./sleep_example
预期输出:

(图片来源网络,侵删)
程序开始运行...
准备睡眠 5 秒...
(等待 5 秒后)
睡眠结束!
程序继续运行。
测试中断:
你可以再运行一次程序,在它睡眠时迅速按下 Ctrl+C,你会看到类似下面的输出:
程序开始运行...
准备睡眠 5 秒...
^C睡眠被中断,还剩 3 秒。
程序继续运行。
(这里的 "3" 是一个示例,具体剩余时间取决于你按下 Ctrl+C 的时机)。
更精确的方法:nanosleep()
当你需要比秒更精确的时间控制时,比如毫秒甚至纳秒级别,sleep() 就不够用了,这时,nanosleep() 是更好的选择。
函数原型
nanosleep() 在 time.h 头文件中声明。

(图片来源网络,侵删)
#include <time.h> int nanosleep(const struct timespec *req, struct timespec *rem);
参数和返回值
- 参数
req: 指向一个timespec结构体的指针,它指定了希望睡眠的时间。timespec结构体定义如下:struct timespec { time_t tv_sec; // 秒 (seconds) long tv_nsec; // 纳秒 (nanoseconds) };- 你需要设置
tv_sec和tv_nsec来组合成你想要的睡眠时长。
- 参数
rem: 这是一个 "剩余时间" 指针。nanosleep()被信号中断,它会在这里写入剩余的睡眠时间,如果你不关心剩余时间,可以传入NULL。 - 返回值:
- 成功时返回 0。
- 被信号中断时返回 -1,并设置
errno为EINTR。rem参数(如果非NULL)会被更新为剩余的睡眠时间。
示例代码
下面的例子演示了如何睡眠 2 秒 500 毫秒(即 2.5 秒)。
#include <stdio.h>
#include <time.h> // 必须包含此头文件
#include <errno.h> // 用于错误处理
int main() {
struct timespec req, rem;
req.tv_sec = 2; // 设置秒数
req.tv_nsec = 500000000; // 设置纳秒数 (500,000,000 ns = 0.5 s)
printf("准备睡眠 2.5 秒...\n");
// 调用 nanosleep
while (nanosleep(&req, &rem) == -1) {
// 如果被信号中断,errno 会被设置为 EINTR
if (errno == EINTR) {
printf("睡眠被中断,剩余时间: %ld.%09ld 秒\n", rem.tv_sec, rem.tv_nsec);
// 将剩余时间重新设置为 req,以便继续睡眠
req = rem;
} else {
// 如果是其他错误,则退出
perror("nanosleep error");
return 1;
}
}
printf("睡眠结束!\n");
return 0;
}
如何编译和运行
gcc nanosleep_example.c -o nanosleep_example ./nanosleep_example
预期输出:
准备睡眠 2.5 秒...
(等待 2.5 秒后)
睡眠结束!
其他方法简介
| 方法 | 头文件 | 精度 | 特点 |
|---|---|---|---|
sleep() |
unistd.h |
秒 | 最简单,标准 POSIX 函数。 |
nanosleep() |
time.h |
纳秒 | 高精度,可被信号中断并恢复,是现代 Linux 程序的首选。 |
usleep() |
unistd.h |
微秒 | 精度比 sleep() 高,但比 nanosleep() 低。注意:在最新的 POSIX 标准中,usleep() 已被标记为过时,不推荐在新代码中使用。 |
select() |
sys/select.h |
微秒 | 主要用于 I/O 多路复用,但可以将其 timeout 参数设置为 NULL 来实现睡眠。 |
timer_create() |
time.h, signal.h |
纳秒 | 最复杂,用于创建高精度的定时器,在指定时间后向进程发送信号,适用于需要周期性或高精度定时任务的场景。 |
总结与选择建议
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 简单的延时,精度要求不高(秒级) | sleep() |
代码最简单,可读性最好。 |
| 需要高精度延时(毫秒、纳秒级) | nanosleep() |
精度高,功能强大,是现代 C 语言的推荐做法。 |
| 旧代码维护或兼容性要求 | usleep() |
虽然可用,但应尽量避免,未来可能被移除。 |
| 需要周期性或复杂定时任务 | timer_create() |
功能最强大,但实现也最复杂。 |
对于绝大多数在 Linux 下进行 C 语言开发的场景,sleep() 和 nanosleep() 是你最主要会使用的两个函数,当你需要秒级精度时用 sleep(),需要更高精度时,毫不犹豫地选择 nanosleep()。
