timer_create
函数创建一个定时器,然后使用 timer_settime
来启动它。创建一个每秒触发一次的定时器,可以使用以下代码:“ c,#include,#include,#include,#include,#includevoid timer_handler(int signum) {, static int count = 0;, printf("Timer expired %d times,", ++count);,}int main() {, struct sigaction sa;, struct itimerspec its;, timer_t timerid;, int res; // 设置信号处理函数, sa.sa_flags = SA_SIGINFO;, sa.sa_sigaction = timer_handler;, sigemptyset(&sa.sa_mask);, if (sigaction(SIGRTMIN, &sa, NULL) == -1) {, perror("sigaction");, return 1;, } // 创建定时器, res = timer_create(CLOCK_REALTIME, NULL, &timerid);, if (res == -1) {, perror("timer_create");, return 1;, } // 设置定时器时间, its.it_value.tv_sec = 1;, its.it_value.tv_nsec = 0;, its.it_interval.tv_sec = 1;, its.it_interval.tv_nsec = 0;, res = timer_settime(timerid, 0, &its, NULL);, if (res == -1) {, perror("timer_settime");, return 1;, } // 等待定时器超时, while (1) {, pause();, } return 0;,},
“
在Linux环境下使用C语言实现定时器有多种方法,以下是几种常见的方式及其详细解释:
1、使用alarm()
函数
原理:alarm()
函数用于设置一个计时器,当计时器到期时,会发送SIGALRM信号给进程。
示例代码
#include <stdio.h> #include <unistd.h> #include <signal.h> void signal_handler(int signum) { printf("Timer expired "); } int main() { signal(SIGALRM, signal_handler); // 设置信号处理函数 alarm(5); // 设置5秒定时器 while (1) { // 主循环 } return 0; }
说明:在这个例子中,alarm(5)
设置了一个5秒的定时器,当定时器到期时,SIGALRM信号会被发送给进程,并且signal_handler
函数会被调用,这种方式适用于需要执行一次性的超时处理场景。
2、使用setitimer()
函数
原理:setitimer()
函数提供了更高精度和更灵活的定时器设置,它可以设置三种类型的计时器:ITIMER_REAL、ITIMER_VIRTUAL、ITIMER_PROF。
示例代码
#include <stdio.h> #include <unistd.h> #include <signal.h> #include <sys/time.h> void signal_handler(int signum) { printf("Timer expired "); } int main() { struct itimerval timer; signal(SIGALRM, signal_handler); // 设置信号处理函数 timer.it_value.tv_sec = 5; // 初始计时器值 timer.it_value.tv_usec = 0; timer.it_interval.tv_sec = 0; // 重复计时器值 timer.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &timer, NULL); // 设置定时器 while (1) { // 主循环 } return 0; }
说明:在这个例子中,setitimer(ITIMER_REAL, &timer, NULL)
设置了一个5秒的定时器,当定时器到期时,SIGALRM信号会被发送给进程,并且signal_handler
函数会被调用,与alarm()
函数不同,setitimer()
可以设置重复定时器。
3、使用线程和usleep()
或nanosleep()
函数
原理:通过创建一个新的线程来处理定时任务,并使用usleep()
或nanosleep()
函数来实现延迟。
示例代码(使用usleep()
)
#include <stdio.h> #include <unistd.h> #include <pthread.h> void* timer_thread(void* arg) { while (1) { usleep(5000000); // 5秒 printf("Timer expired "); } return NULL; } int main() { pthread_t thread_id; pthread_create(&thread_id, NULL, timer_thread, NULL); pthread_join(thread_id, NULL); return 0; }
示例代码(使用nanosleep()
)
#include <stdio.h> #include <time.h> #include <pthread.h> void* timer_thread(void* arg) { struct timespec ts; ts.tv_sec = 5; // 5秒 ts.tv_nsec = 0; while (1) { nanosleep(&ts, NULL); printf("Timer expired "); } return NULL; } int main() { pthread_t thread_id; pthread_create(&thread_id, NULL, timer_thread, NULL); pthread_join(thread_id, NULL); return 0; }
说明:这两个例子中,分别使用了usleep()
和nanosleep()
函数来实现定时器,每隔5秒打印一次"Timer expired",这种方式适用于需要在后台运行定时任务的场景。
4、使用POSIX定时器
原理:POSIX定时器提供了更加精确和灵活的定时器功能,可以使用timer_create()
、timer_settime()
和timer_delete()
函数来创建和管理定时器。
示例代码
#include <stdio.h> #include <signal.h> #include <time.h> #include <unistd.h> void handle_timer(union sigval sv) { printf("Timer expired "); } int main() { timer_t timerid; struct sigevent sev; struct itimerspec its; struct sigaction sa; sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = handle_timer; sigemptyset(&sa.sa_mask); sigaction(SIGRTMIN, &sa, NULL); // 使用 SIGRTMIN 或其他未使用的实时信号 sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGRTMIN; sev.sigev_value.sival_ptr = &timerid; if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) { perror("timer_create"); return 1; } its.it_value.tv_sec = 3; // 初始到期时间 its.it_value.tv_nsec = 0; its.it_interval.tv_sec = 3; // 间隔时间 its.it_interval.tv_nsec = 0; if (timer_settime(timerid, 0, &its, NULL) == -1) { perror("timer_settime"); return 1; } while (1) { pause(); // 等待信号 } return 0; }
说明:在这个例子中,创建了一个POSIX定时器,每隔3秒触发一次定时器到期事件,并调用handle_timer
函数,这种方式适用于需要高精度和复杂定时任务的场景。
在Linux下使用C语言实现定时器的方法多种多样,开发者可以根据具体需求选择合适的方法,无论是简单的一次性定时任务还是复杂的周期性任务,都能在这些方法中找到合适的解决方案。