在 C 语言中使用 nanosleep 函数

Jinku Hu 2023年10月12日
  1. 在 C 语言中使用 nanosleep 函数用高分辨率定时器暂停程序执行
  2. 检查 C 语言中的 nanosleep 函数是否执行成功
在 C 语言中使用 nanosleep 函数

本文将介绍几种在 C 语言中使用 nanosleep 函数的方法。

在 C 语言中使用 nanosleep 函数用高分辨率定时器暂停程序执行

nanosleep 是一个符合 POSIX 标准的系统调用,用于在给定的固定时间段内暂停程序的执行。其他函数也提供了做同样操作的设施,sleep 是其中之一,它需要若干秒来暂停调用进程。sleep 可以说是提供了低分辨率的暂停。而 nanosleep 则允许用户以纳秒的精度指定睡眠时间。

nanosleep 函数需要两个类型为 struct timespec 对象的地址,这两个地址都有两个数据成员。tv_sec-代表秒数,tv_nsec-表示纳秒数。第一个 timespec 结构用来指定悬浮的时间段。注意,tv_nsec 值必须在 0 到 999999999 的范围内,否则,调用会失败。在下面的例子中,我们执行一个有 10 次迭代的循环,并在第 5 个周期通过调用 nanosleep 暂停进程。

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

enum { SECS_TO_SLEEP = 3, NSEC_TO_SLEEP = 125 };

int main() {
  struct timespec remaining, request = {SECS_TO_SLEEP, NSEC_TO_SLEEP};

  printf("Started loop..\n");
  for (int i = 0; i < 10; ++i) {
    printf("Iteration - %d\n", i);
    if (i == 4) {
      printf("Sleeping ....\n");
      nanosleep(&request, &remaining);
    }
  }

  exit(EXIT_SUCCESS);
}

输出:

Started loop..
Iteration - 0
Iteration - 1
Iteration - 2
Iteration - 3
Iteration - 4
Sleeping ....
Iteration - 5
Iteration - 6
Iteration - 7
Iteration - 8
Iteration - 9

检查 C 语言中的 nanosleep 函数是否执行成功

尽管 nanosleep 应该在给定的时间段内暂停进程,但系统中的一些事件会打断它,迫使函数返回错误代码,并将 errno 设置为 EINTR。在这种情况下,第二个 timespec 参数用来存储函数调用被信号中断的剩余时间段。这个对象随后可以再次调用 nanosleep,希望这次能完成睡眠。接下来的例子演示了如何检查多个错误代码,打印相应的信息,并根据需要处理代码执行。

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

enum { SECS_TO_SLEEP = 3, NSEC_TO_SLEEP = 125 };

int main() {
  struct timespec remaining, request = {SECS_TO_SLEEP, NSEC_TO_SLEEP};

  printf("Started loop..\n");
  for (int i = 0; i < 10; ++i) {
    printf("Iteration - %d\n", i);
    if (i == 4) {
      printf("Sleeping ....\n");

      errno = 0;
      if (nanosleep(&request, &remaining) == -1) {
        switch (errno) {
          case EINTR:
            printf("interrupted by a signal handler\n");
            exit(EXIT_FAILURE);
          case EINVAL:
            printf("tv_nsec - not in range or tv_sec is negative\n");
            exit(EXIT_FAILURE);
          default:
            perror("nanosleep");
            exit(EXIT_FAILURE);
        }
      }
    }
  }

  exit(EXIT_SUCCESS);
}

输出:

Started loop..
Iteration - 0
Iteration - 1
Iteration - 2
Iteration - 3
Iteration - 4
Sleeping ....
Iteration - 5
Iteration - 6
Iteration - 7
Iteration - 8
Iteration - 9
作者: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 创始人。Jinku 在机器人和汽车行业工作了8多年。他在自动测试、远程测试及从耐久性测试中创建报告时磨练了自己的编程技能。他拥有电气/电子工程背景,但他也扩展了自己的兴趣到嵌入式电子、嵌入式编程以及前端和后端编程。

LinkedIn Facebook