在 Linux 系统中,定时器的实现方法有多种,具体选择取决于应用场景和精度要求。以下是常见的实现方式及其详细说明:
sleep()
和 usleep()
c
sleep(5); // 阻塞5秒
usleep(500000); // 阻塞500毫秒
alarm()
和信号(SIGALRM)示例: ```c #include <signal.h> #include <unistd.h>
void handler(int sig) { printf("Timer expired!\n"); }
int main() { signal(SIGALRM, handler); alarm(5); // 5秒后触发SIGALRM while(1) pause(); // 等待信号 } ```
setitimer()
alarm()
更精确的周期性定时器(微秒级)。ITIMER_REAL
(真实时间)、ITIMER_VIRTUAL
(进程用户态时间)等。示例: ```c #include <sys/time.h>
void handler(int sig) { printf("Timer triggered.\n"); }
int main() { struct itimerval timer; signal(SIGALRM, handler);
timer.it_value.tv_sec = 1; // 首次触发延迟1秒
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 1; // 后续间隔1秒
timer.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &timer, NULL);
while(1) pause();
} ```
timer_create()
)SIGEV_SIGNAL
)或线程回调(SIGEV_THREAD
)。示例(信号通知): ```c #include <time.h> #include <signal.h>
void handler(int sig, siginfo_t *si, void *uc) { printf("POSIX timer fired.\n"); }
int main() { timer_t timerid; struct sigevent sev; struct itimerspec its;
// 设置信号处理
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigaction(SIGRTMIN, &sa, NULL);
// 配置定时器事件
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN;
sev.sigev_value.sival_ptr = &timerid;
timer_create(CLOCK_REALTIME, &sev, &timerid);
// 设置首次1秒触发,之后每0.5秒一次
its.it_value.tv_sec = 1;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 500000000;
timer_settime(timerid, 0, &its, NULL);
while(1) pause();
} ```
epoll
/select
超时机制示例: ```c #include <sys/epoll.h>
int main() { int epfd = epoll_create1(0); struct epoll_event ev; int timeout_ms = 5000; // 5秒超时
while(1) {
int n = epoll_wait(epfd, &ev, 1, timeout_ms);
if (n == 0) {
printf("Timeout occurred!\n");
}
}
} ```
add_timer()
)jiffies
(内核时间单位),精度依赖内核配置。示例(内核模块): ```c #include <linux/timer.h>
static struct timer_list my_timer;
void timer_callback(struct timer_list *t) { printk("Kernel timer expired!\n"); mod_timer(&my_timer, jiffies + msecs_to_jiffies(2000)); // 重新设置2秒后触发 }
static int __init my_init(void) { timer_setup(&my_timer, timer_callback, 0); mod_timer(&my_timer, jiffies + msecs_to_jiffies(2000)); return 0; } ```
libuv
、Boost.Asio
)示例(libuv): ```c #include <uv.h>
void callback(uv_timer_t *handle) { printf("Libuv timer callback.\n"); }
int main() { uv_loop_t *loop = uv_default_loop(); uv_timer_t timer; uv_timer_init(loop, &timer); uv_timer_start(&timer, callback, 1000, 2000); // 首次1秒后触发,之后每2秒一次 uv_run(loop, UV_RUN_DEFAULT); } ```
sleep
或 usleep
。setitimer
或 POSIX 定时器。timer_create
)。epoll
或异步库(如 libuv
)。根据具体场景选择合适的方法,并注意信号安全性和线程兼容性。