C语言在Linux下如何正确使用sleep函数?

99ANYc3cd6
预计阅读时长 13 分钟
位置: 首页 C语言 正文

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

c语言 linux sleep
(图片来源网络,侵删)

标准方法: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;
}

如何编译和运行

  1. 将代码保存为 sleep_example.c
  2. 打开终端,使用 gcc 进行编译:
    gcc sleep_example.c -o sleep_example
  3. 运行生成的可执行文件:
    ./sleep_example

预期输出:

c语言 linux sleep
(图片来源网络,侵删)
程序开始运行...
准备睡眠 5 秒...
(等待 5 秒后)
睡眠结束!
程序继续运行。

测试中断: 你可以再运行一次程序,在它睡眠时迅速按下 Ctrl+C,你会看到类似下面的输出:

程序开始运行...
准备睡眠 5 秒...
^C睡眠被中断,还剩 3 秒。
程序继续运行。

(这里的 "3" 是一个示例,具体剩余时间取决于你按下 Ctrl+C 的时机)。


更精确的方法:nanosleep()

当你需要比秒更精确的时间控制时,比如毫秒甚至纳秒级别,sleep() 就不够用了,这时,nanosleep() 是更好的选择。

函数原型

nanosleep()time.h 头文件中声明。

c语言 linux sleep
(图片来源网络,侵删)
#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_sectv_nsec 来组合成你想要的睡眠时长。
  • 参数 rem: 这是一个 "剩余时间" 指针。nanosleep() 被信号中断,它会在这里写入剩余的睡眠时间,如果你不关心剩余时间,可以传入 NULL
  • 返回值:
    • 成功时返回 0
    • 被信号中断时返回 -1,并设置 errnoEINTRrem 参数(如果非 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()

-- 展开阅读全文 --
头像
dede织梦后台登录界面乱码咋办?
« 上一篇 01-10
Linux C中system函数安全使用注意事项?
下一篇 » 01-10

相关文章

取消
微信二维码
支付宝二维码

目录[+]