面试题答案
一键面试设计架构
- 任务结构体:定义一个结构体来表示每个任务,包含任务函数指针、执行周期、上次执行时间等信息。
- 定时器管理结构体:用于管理所有任务,包含任务链表头指针等。
- 链表管理:使用链表来存储所有任务,便于添加、删除任务。
- 定时器驱动:利用Linux的定时器机制(如
setitimer
)来触发定时事件,在定时回调函数中检查各个任务是否到了执行时间。
关键代码实现
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <time.h>
// 定义任务结构体
typedef struct Task {
void (*func)(); // 任务函数指针
unsigned long period; // 任务执行周期(毫秒)
unsigned long last_exec_time; // 上次执行时间
struct Task *next;
} Task;
// 定义定时器管理结构体
typedef struct TimerManager {
Task *head;
} TimerManager;
// 初始化定时器管理模块
void init_timer_manager(TimerManager *tm) {
tm->head = NULL;
}
// 添加任务
void add_task(TimerManager *tm, void (*func)(), unsigned long period) {
Task *new_task = (Task *)malloc(sizeof(Task));
new_task->func = func;
new_task->period = period;
new_task->last_exec_time = 0;
new_task->next = tm->head;
tm->head = new_task;
}
// 删除任务(这里简单实现,实际可优化)
void remove_task(TimerManager *tm, void (*func)()) {
Task *prev = NULL;
Task *curr = tm->head;
while (curr != NULL && curr->func != func) {
prev = curr;
curr = curr->next;
}
if (curr == NULL) return;
if (prev == NULL) {
tm->head = curr->next;
} else {
prev->next = curr->next;
}
free(curr);
}
// 定时器回调函数
void timer_callback(int signum) {
struct timeval now;
gettimeofday(&now, NULL);
unsigned long current_time = now.tv_sec * 1000 + now.tv_usec / 1000;
extern TimerManager timer_manager;
Task *curr = timer_manager.head;
while (curr != NULL) {
if (curr->last_exec_time == 0 || current_time - curr->last_exec_time >= curr->period) {
curr->func();
curr->last_exec_time = current_time;
}
curr = curr->next;
}
}
// 设置定时器
void setup_timer(unsigned long interval) {
struct itimerval itv;
itv.it_value.tv_sec = interval / 1000;
itv.it_value.tv_usec = (interval % 1000) * 1000;
itv.it_interval.tv_sec = interval / 1000;
itv.it_interval.tv_usec = (interval % 1000) * 1000;
setitimer(ITIMER_REAL, &itv, NULL);
signal(SIGALRM, timer_callback);
}
// 示例任务函数
void sample_task() {
printf("Sample task executed\n");
}
int main() {
TimerManager timer_manager;
init_timer_manager(&timer_manager);
add_task(&timer_manager, sample_task, 1000); // 每1秒执行一次
setup_timer(100); // 每100毫秒检查一次任务
while (1) {
// 主循环可以做其他事情
}
return 0;
}
上述代码中,定义了任务结构体和定时器管理结构体,实现了任务的添加、删除,利用setitimer
和SIGALRM
信号实现了定时检查任务执行的功能。实际应用中,还需要考虑线程安全、错误处理等更多方面。