设计思路
- 使用
setitimer
函数:setitimer
函数用于设置定时器,它可以指定定时器的间隔时间和首次到期时间。通过设置合适的时间参数,我们可以实现周期性触发定时器。
- 信号处理机制:当定时器到期时,系统会发送一个信号(通常是
SIGALRM
)。我们需要注册一个信号处理函数来处理这个信号,在信号处理函数中打印当前系统时间。
- 处理竞态条件:竞态条件可能出现在信号处理函数与主程序共享某些资源时。为了避免竞态条件,可以使用互斥锁(
pthread_mutex_t
)来保护共享资源。在访问共享资源前加锁,访问结束后解锁。
关键代码片段
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <pthread.h>
#include <time.h>
// 定义互斥锁
pthread_mutex_t mutex;
// 信号处理函数
void signal_handler(int signum) {
pthread_mutex_lock(&mutex);
time_t now;
struct tm *tm_info;
time(&now);
tm_info = localtime(&now);
char time_str[26];
strftime(time_str, 26, "%Y-%m-%d %H:%M:%S", tm_info);
printf("Current time: %s\n", time_str);
pthread_mutex_unlock(&mutex);
}
int main() {
// 初始化互斥锁
pthread_mutex_init(&mutex, NULL);
// 注册信号处理函数
struct sigaction sa;
sa.sa_handler = signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
// 设置定时器
struct itimerval itv;
itv.it_value.tv_sec = 1; // 首次到期时间为1秒
itv.it_value.tv_usec = 0;
itv.it_interval.tv_sec = 1; // 间隔时间为1秒
itv.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
// 主循环,防止程序退出
while (1) {
// 这里可以执行其他任务
}
// 清理互斥锁
pthread_mutex_destroy(&mutex);
return 0;
}