在 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