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