setitimer 是 Linux 提供的進程級高精度定時器介面,支援三種計時模式,能在微秒級觸發訊號,適用於定時任務、效能分析、多媒體同步等場景。本文詳細解析 API、參數結構、訊號機制並提供完整可編譯範例。
| 計時器類型 | 宏常數 | 計時域 | 觸發訊號 | 典型用途 |
|---|---|---|---|---|
| 實時計時器 | ITIMER_REAL | 牆鐘時間 (wall-clock) | SIGALRM | 一般定時任務、閒置檢測 |
| 虛擬計時器 | ITIMER_VIRTUAL | 進程用戶態 CPU 時間 | SIGVTALRM | 使用者程式碼效能分析 |
| 剖析計時器 | ITIMER_PROF | 進程用戶態+核心態 CPU 時間 | SIGPROF | 全稱效能剖析 (含系統呼叫) |
關鍵限制:每個進程同一時間只能擁有一個
setitimer定時器,後設定會覆蓋前設定。需多定時器請自行實現 (如timerfd、epoll+ 事件循環)。
#include <sys/time.h>
int getitimer(int which, struct itimerval *value);
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
結構體定義:
struct itimerval {
struct timeval it_interval; // 週期間隔 (觸發後自動重裝載)
struct timeval it_value; // 初次觸發倒數
};
struct timeval {
long tv_sec; // 秒
long tv_usec; // 微秒 (10^-6 秒)
};
it_value:首次倒數歸零觸發訊號,若為 0 則停用定時器。it_interval:非 0 時,觸發後自動重載此值實現週期性觸發;為 0 則僅觸發一次。#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/time.h>
#include <errno.h>
void timer_handler(int signo) {
// 訊號處理函數務必保持簡短、非阻塞、可重入
write(STDOUT_FILENO, "Hello World\n", 12);
}
int main() {
// 1. 註冊訊號處理
signal(SIGALRM, timer_handler);
// 2. 設定定時器參數
struct itimerval tick = {0};
tick.it_value.tv_sec = 2; // 2 秒後首次觸發
tick.it_value.tv_usec = 0;
tick.it_interval.tv_sec = 1; // 之後每 1 秒觸發
tick.it_interval.tv_usec = 0;
// 3. 啟動 ITIMER_REAL 定時器
if (setitimer(ITIMER_REAL, &tick, NULL) == -1) {
perror("setitimer failed");
return -1;
}
printf("Timer started. Press Enter to exit...\n");
getchar(); // 等待使用者輸入結束
// 4. 停用定時器 (可選)
struct itimerval zero = {0};
setitimer(ITIMER_REAL, &zero, NULL);
return 0;
}
gcc -o timer_demo timer_demo.c
./timer_demo
| errno | 宏 | 原因 |
|---|---|---|
| EFAULT | Bad address | value 或 ovalue 指標無效 |
| EINVAL | Invalid argument | which 非三種合法類型,或 tv_usec ≥ 1,000,000 |
write、_exit),嚴禁 printf、malloc、pthread_mutex_lock 等。timer_create + SIGRTMIN (即時訊號支援排隊)。pthread_sigmask 控制。HZ,通常 100~1000Hz),實際精度約 1~10ms;微秒級參數會被向上取整。納秒級需求請用 timer_create + CLOCK_MONOTONIC。| 介面 | 精度 | 多定時器 | 訊號排隊 | 複雜度 |
|---|---|---|---|---|
setitimer | ~1ms | ❌ (單一) | ❌ | 低 |
timer_create (POSIX Timer) | 納秒級 | ✅ | ✅ (SIGRT) | 中 |
timerfd (Linux 專用) | 納秒級 | ✅ | ✅ (epoll 整合) | 中 |
sleep/usleep/nanosleep | 毫秒~微秒 | N/A (阻塞) | N/A | 極低 |
setitimer 雖屬經典介面,但在現代高併發、高精度場景下,建議優先考慮 timerfd + epoll 事件驅動模型,獲得更好的擴展性與精度控制。
如何在 Linux 系統中禁用 SCP 與 SFTP 命令以增強安全性
Linux 配置 rdate 時間同步:外部時間源與內網時間伺服器雙模式
RedHat Linux 5 ifconfig 指令找不到解決方案:PATH 環境變數缺失 /sbin 路徑
Linux rm 指令完全指南:參數詳解、刪除目錄與安全刪除技巧
VNC 遠程連線 Linux 桌面完整教學:Server 安裝、配置、密碼、防火牆、Viewer 連線
RHEL 6.0 sudo 切换用户极慢:/etc/hosts 缺少主机名映射导致
Linux startx 指令詳解:啟動 X Window 系統的腳本封裝與參數傳遞機制
Ubuntu USB 開機報錯 "BOOT ERROR" 解決方案:BIOS USB 模式 (ZIP/HDD/Auto) 與啟動順序調整實戰