
傳統 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; // 首次觸發時間
};
struct itimerval val = {
.it_value = {2, 500000},
.it_interval = {2, 500000}
};
setitimer(ITIMER_REAL, &val, NULL);
struct itimerval val = {
.it_value = {1, 0},
.it_interval = {3, 0}
};
setitimer(ITIMER_VIRTUAL, &val, NULL);
struct itimerval val = {{0, 0}, {0, 0}}; // it_value 歸零即停止
setitimer(ITIMER_PROF, &val, NULL);
struct itimerval val = {
.it_value = {1, 500000},
.it_interval = {0, 0} // 間隔為 0,單次觸發
};
setitimer(ITIMER_REAL, &val, NULL);
#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 等非安全函數。靈活運用 setitimer 三大定時器,能精準掌控程序時間行為,是系統級開發者的必備技能。