MST

星途 面试题库

面试题:C语言Linux定时器在多任务中的应用

假设在一个实时系统中有多个任务,每个任务都有不同的执行周期,使用C语言在Linux下设计一个定时器管理模块,使得这些任务能按照各自周期准确执行,阐述设计架构和关键代码实现。
41.9万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

设计架构

  1. 任务结构体:定义一个结构体来表示每个任务,包含任务函数指针、执行周期、上次执行时间等信息。
  2. 定时器管理结构体:用于管理所有任务,包含任务链表头指针等。
  3. 链表管理:使用链表来存储所有任务,便于添加、删除任务。
  4. 定时器驱动:利用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;
}

上述代码中,定义了任务结构体和定时器管理结构体,实现了任务的添加、删除,利用setitimerSIGALRM信号实现了定时检查任务执行的功能。实际应用中,还需要考虑线程安全、错误处理等更多方面。