在 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