在 C 语言中使用 nanosleep 函数
Jinku Hu
2023年10月12日
本文将介绍几种在 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