MST

星途 面试题库

面试题:C语言Linux定时器任务取消的资源管理问题

在Linux下使用C语言创建定时器并设置定时任务,当取消定时任务时,详细说明如何确保相关资源(如内存、文件描述符等)被正确释放,防止内存泄漏和资源未关闭的情况,同时给出代码示例。
21.6万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
  1. 创建定时器并设置定时任务: 在Linux下可以使用POSIX定时器(timer_create等函数)来创建定时器并设置定时任务。以下是一个基本的步骤:
    • 使用timer_create函数创建定时器。
    • 使用struct sigevent结构体来指定定时器到期时的行为,例如发送信号。
    • 使用timer_settime函数来启动定时器。
  2. 取消定时任务并释放资源
    • 使用timer_delete函数来取消定时器,这个函数会自动释放与定时器相关的资源。
    • 如果在定时器到期处理函数中分配了内存或打开了文件描述符等资源,需要在处理函数内部或调用timer_delete之前确保这些资源被正确释放。例如,对于动态分配的内存使用free函数释放,对于打开的文件描述符使用close函数关闭。
  3. 代码示例
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>

// 定时器到期时的信号处理函数
void timer_handler(int signum) {
    static int count = 0;
    printf("Timer expired %d times\n", ++count);
    // 假设这里分配了内存
    int *ptr = (int *)malloc(sizeof(int));
    if (ptr) {
        free(ptr);
    }
    // 假设这里打开了文件描述符
    int fd = open("test.txt", O_RDONLY);
    if (fd != -1) {
        close(fd);
    }
}

int main() {
    struct sigevent sev;
    struct itimerspec its;
    timer_t timerid;

    // 初始化信号处理函数
    struct sigaction sa;
    sa.sa_handler = &timer_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGUSR1, &sa, NULL) == -1) {
        perror("sigaction");
        return 1;
    }

    // 设置定时器属性
    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIGUSR1;
    sev.sigev_value.sival_ptr = &timerid;
    if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {
        perror("timer_create");
        return 1;
    }

    // 设置定时器的初始值和周期
    its.it_value.tv_sec = 2;  // 2秒后首次触发
    its.it_value.tv_nsec = 0;
    its.it_interval.tv_sec = 2;  // 每2秒触发一次
    its.it_interval.tv_nsec = 0;
    if (timer_settime(timerid, 0, &its, NULL) == -1) {
        perror("timer_settime");
        return 1;
    }

    printf("Timer started. Press any key to cancel...\n");
    getchar();

    // 取消定时器
    if (timer_delete(timerid) == -1) {
        perror("timer_delete");
        return 1;
    }
    printf("Timer canceled.\n");

    return 0;
}

在上述代码中:

  • timer_handler函数是定时器到期时的信号处理函数,在这个函数中模拟了内存分配和文件描述符打开,并在函数内部正确释放了这些资源。
  • main函数中创建了定时器,设置了定时任务,然后等待用户输入,用户输入后取消定时器并释放相关资源。timer_delete函数确保了定时器相关资源的正确释放。