首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

精通 Unix 高精度定時器:setitimer 實戰詳解

     編輯:關於C語言

定時器示意圖

為什麼需要高精度定時器?

傳統 alarm() 僅支持秒級精度且無法重複觸發。現代系統編程常需毫秒/微秒級定時、週期性觸發、區分用戶態/核心態執行時間,這正是 setitimer() 與 getitimer() 的用武之地。

三種獨立定時器類型

類型常量計時範圍觸發信號典型應用
ITIMER_REAL真實時間(牆鐘時間)SIGALRM網絡超時、定時任務調度
ITIMER_VIRTUAL進程用戶態 CPU 時間SIGVTALRM用戶代碼性能分析
ITIMER_PROF用戶態+核心態 CPU 時間SIGPROF全程序性能剖析

核心數據結構

struct timeval {
    long tv_sec;   // 秒
    long tv_usec;  // 微秒
};

struct itimerval {
    struct timeval it_interval; // 週期間隔(0 表單次觸發)
    struct timeval it_value;    // 首次觸發時間
};

四大經典使用場景代碼模板

場景 1:週期性真實時間定時器(每 2.5 秒觸發 SIGALRM)

struct itimerval val = {
    .it_value    = {2, 500000},
    .it_interval = {2, 500000}
};
setitimer(ITIMER_REAL, &val, NULL);

場景 2:用戶態 CPU 時間分析(首次 1 秒,之後每 3 秒)

struct itimerval val = {
    .it_value    = {1, 0},
    .it_interval = {3, 0}
};
setitimer(ITIMER_VIRTUAL, &val, NULL);

場景 3:取消特定定時器

struct itimerval val = {{0, 0}, {0, 0}}; // it_value 歸零即停止
setitimer(ITIMER_PROF, &val, NULL);

場景 4:單次觸發定時器(1.5 秒後發送一次 SIGALRM)

struct itimerval val = {
    .it_value    = {1, 500000},
    .it_interval = {0, 0} // 間隔為 0,單次觸發
};
setitimer(ITIMER_REAL, &val, NULL);

完整實戰範例:ITIMER_PROF 週期性打印計數器

#include <sys/time.h>
#include <signal.h>
#include <stdio.h>

int count = 0;
void handler(int sig) {
    fprintf(stderr, "ITIMER_PROF[%d]\n", count++);
    signal(SIGPROF, handler); // 重新註冊(舊版 Unix 需求)
}

int main() {
    struct itimerval val = {
        .it_value    = {1, 500000}, // 1.5 秒
        .it_interval = {1, 500000}
    };
    signal(SIGPROF, handler);
    setitimer(ITIMER_PROF, &val, NULL);
    while (1); // 模擬計算負載
    return 0;
}

關鍵注意事項

  • 互斥性:進程中不可同時使用 alarm() 與 ITIMER_REAL,二者共用同一硬件定時器。
  • 信號重入:處理函數中只調用異步信號安全函數(如 write、_exit),避免調用 printf、malloc 等非安全函數。
  • 精度限制:理論微秒級,實際受系統時鐘中斷頻率(如 100Hz/1000Hz)限制,通常為毫秒級。

靈活運用 setitimer 三大定時器,能精準掌控程序時間行為,是系統級開發者的必備技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved