如何在Linux中创建微秒级定时器间隔?以及C/C++实现精确50usec中断式定时器的标准方法咨询
1. Creating Microsecond-Level Timer Intervals in Linux
Great question—microsecond-level timing on Linux depends a lot on whether you're working in user space or kernel space, and how strict your precision needs are. Here are the most reliable approaches:
User-Space Methods
timerfd(POSIX Standard, Preferred)
This is the modern, file-descriptor-based timer interface that plays nicely withepollorselect, making it easy to slot into event-driven apps. It supports microsecond precision as long as your kernel has high-resolution timers enabled (most modern distros have this turned on by default).Example C code snippet:
#include <sys/timerfd.h> #include <stdio.h> #include <unistd.h> #include <stdint.h> int main() { int timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); if (timer_fd == -1) { perror("timerfd_create"); return 1; } struct itimerspec timer_spec; // Fire immediately on start timer_spec.it_value.tv_sec = 0; timer_spec.it_value.tv_nsec = 1; // Set interval to 50 microseconds (50,000 nanoseconds) timer_spec.it_interval.tv_sec = 0; timer_spec.it_interval.tv_nsec = 50 * 1000; if (timerfd_settime(timer_fd, 0, &timer_spec, NULL) == -1) { perror("timerfd_settime"); close(timer_fd); return 1; } uint64_t expirations; while (1) { ssize_t bytes_read = read(timer_fd, &expirations, sizeof(expirations)); if (bytes_read == sizeof(expirations)) { printf("Timer fired %llu times\n", (unsigned long long)expirations); // Your 50us interval logic goes here } } close(timer_fd); return 0; }setitimer(Legacy POSIX)
An older interface that sends signals (likeSIGALRM) when the timer expires. Keep in mind that signal delivery can have noticeable jitter due to kernel scheduling, so it's less reliable for strict microsecond timing compared totimerfd.
Kernel-Space Methods
If you need rock-solid, interrupt-level precision (e.g., for hardware control), you'll need to write a kernel module using the kernel's hrtimer API, which supports nanosecond-level granularity directly in the kernel.
2. Standard Method for a Precise 50usec Interrupt-Based Timer in C/C++ on Linux
First, a quick clarification: true hardware interrupts are kernel-only—user-space code can't directly register interrupt handlers. But we can get extremely close to interrupt-like behavior (low jitter, periodic execution) using kernel-assisted timers, and there are standard POSIX tools to make this happen.
Recommended User-Space Approach (POSIX Standard)
Combine timerfd with real-time scheduling to minimize jitter:
- Verify high-resolution timers are enabled (check
/sys/devices/system/clocksource/clocksource0/current_clocksource—it should show something liketscorhpet). - Set your process to use a real-time scheduling policy (e.g.,
SCHED_FIFO) to avoid being preempted by lower-priority tasks.
Add this snippet to the timerfd example above to enable real-time scheduling:
#include <sched.h> int main() { struct sched_param param; param.sched_priority = sched_get_priority_max(SCHED_FIFO); if (sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) { perror("sched_setscheduler"); // Note: You'll need root privileges for this } // Rest of the timerfd code... }
Kernel-Space "True Interrupt" Timer
If you need actual interrupt-level execution (e.g., for controlling hardware with minimal latency), here's a minimal kernel module skeleton using hrtimer:
#include <linux/module.h> #include <linux/hrtimer.h> #include <linux/ktime.h> static struct hrtimer timer; enum hrtimer_restart timer_callback(struct hrtimer *hr_timer) { // Keep this code SHORT—kernel callbacks can't block! ktime_t now = hrtimer_cb_get_time(hr_timer); hrtimer_forward_now(hr_timer, ns_to_ktime(50 * 1000)); // 50us interval return HRTIMER_RESTART; } static int __init timer_init(void) { ktime_t interval = ns_to_ktime(50 * 1000); hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); timer.function = timer_callback; hrtimer_start(&timer, interval, HRTIMER_MODE_REL); return 0; } static void __exit timer_exit(void) { hrtimer_cancel(&timer); } module_init(timer_init); module_exit(timer_exit); MODULE_LICENSE("GPL");
Key Precision Tips
- Always use
CLOCK_MONOTONICinstead ofCLOCK_REALTIME—it's not affected by system clock changes (like NTP updates). - For user-space code, run as root to access real-time scheduling privileges.
- Kernel timer callbacks must be extremely brief—long code will block the kernel and cause system instability.
内容的提问来源于stack exchange,提问作者Dimpu10




