Ubuntu提供了clock_gettime
、timerfd
等高精度定時器API,相比傳統alarm
或setitimer
,能實現更高精度的時間控制。
clock_gettime
:通過指定CLOCK_MONOTONIC
(系統啟動后的單調遞增時間,不受系統時間調整影響)或CLOCK_REALTIME
(實際時間),獲取納秒級時間戳。例如,獲取當前時間并打印納秒部分:#include <time.h>
#include <stdio.h>
int main() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
printf("Current time: %ld.%09ld\n", ts.tv_sec, ts.tv_nsec);
return 0;
}
timerfd
:創建文件描述符形式的定時器,支持周期性或單次觸發,可與epoll
、read
等系統調用結合,實現高精度的定時任務調度。例如,設置一個100毫秒周期的定時器:#include <sys/timerfd.h>
#include <unistd.h>
#include <stdio.h>
int main() {
int fd = timerfd_create(CLOCK_MONOTONIC, 0);
struct itimerspec new_value = {
.it_interval = {0, 100000000}, // 100毫秒周期
.it_value = {0, 100000000} // 首次觸發時間
};
timerfd_settime(fd, 0, &new_value, NULL);
while (1) {
read(fd, &expirations, sizeof(expirations)); // 阻塞等待定時器觸發
printf("Timer expired\n");
}
}
默認的**CFS(Completely Fair Scheduler)**調度器雖公平,但可能引入調度延遲。通過調整調度參數,可減少延遲,提高定時器精度:
kernel.sched_min_granularity_ns
(最小調度粒度,默認1毫秒),讓調度器更頻繁地切換任務,減少定時器任務的等待時間。例如:sudo sysctl -w kernel.sched_min_granularity_ns=1000000 # 設置為1毫秒(1000000納秒)
kernel.sched_migration_cost_ns
(任務遷移成本,默認1毫秒),減少任務在CPU間遷移的時間,提高定時器任務的執行連續性。例如:sudo sysctl -w kernel.sched_migration_cost_ns=1000 # 設置為1微秒
普通內核采用完全公平調度,無法保證定時器任務的實時性。實時內核(RT-Preempt Patch)通過完全搶占式調度,提高定時器任務的優先級,減少延遲。
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux && git checkout v5.10.0-rt10
(以具體版本為準)make menuconfig
(在“Kernel hacking -> Preemption Model”中選擇“Fully Preemptible Kernel (RT)”),然后執行make -j$(nproc) && sudo make modules_install install
Hz
)為1000(每秒1000次中斷),可通過修改內核啟動參數(如GRUB_CMDLINE_LINUX="clocksource=tsc tsc=reliable"
)或內核配置(CONFIG_HZ_1000=y
),提高時鐘中斷頻率(如2000 Hz),減少定時器誤差。sudo sysctl -w vm.min_free_kbytes=65536 # 增加最小空閑內存
sudo sysctl -w vm.swappiness=10 # 降低Swap傾向(0-100,值越小越不容易Swap)
定時器抖動(實際觸發時間與預期時間的偏差)會嚴重影響精度,需通過以下方式減少:
timerfd_settime
的周期性模式),減少系統調用開銷。CLOCK_MONOTONIC
(不受系統時間調整影響),而非CLOCK_REALTIME
(可能因NTP同步調整)。對于用戶空間的定時器任務,可通過nice
(調整進程優先級)和ionice
(調整I/O優先級),提高任務的執行優先級,減少被其他任務搶占的概率:
nice -n -20 ionice -c 2 -n 0 /path/to/timer_task # 提高進程優先級(nice值越小,優先級越高)
其中,nice -n -20
表示最高優先級,ionice -c 2 -n 0
表示最高I/O優先級。
新版本內核通常會對定時器子系統進行優化(如提高時鐘分辨率、優化調度算法),例如Ubuntu 22.04及以上版本默認使用5.x內核,支持更高效的高精度定時器??赏ㄟ^以下命令升級內核:
sudo apt update && sudo apt upgrade
sudo apt install linux-generic-hwe-22.04 # 安裝最新的HWE內核