编译的时候需要加上 -lrt
timer.h :
#ifdef __cplusplus
extern "C" {
#endif
#ifndef TIMER_API_H
#define TIMER_API_H
#include <signal.h>
#include <time.h>
// 定时器触发方式
typedef enum {
TRIGGER_SIGNAL, // 信号触发
TRIGGER_THREAD, // 线程触发,创建一个线程去执行
} TriggerType;
// 定时器状态
typedef enum {
TIMER_RUNNING, // 运行
TIMER_PAUSED // 暂停
} TimerStatus;
typedef struct {
time_t seconds; // 秒
long nanoseconds; // 纳秒
} TimerInterval;
// 定时器结构体
typedef struct {
timer_t timer_id;
struct itimerspec initial_value;
struct itimerspec current_value;
TimerStatus status;
} Timer;
// 初始化定时器
int timer_init(Timer* timer, TriggerType trigger_type, ...);
// 启动定时器
int timer_start(Timer* timer, TimerInterval interval);
// 暂停定时器
int timer_pause(Timer* timer);
// 恢复定时器
int timer_resume(Timer* timer);
// 重置定时器,重新开始计时
int timer_reset(Timer* timer);
// 重新设置定时器时间间隔
int timer_set_timeInterval(Timer* timer, TimerInterval interval);
// 获取定时器相关信息
int timer_get_time(Timer* timer,
int* status,
TimerInterval* interval,
TimerInterval* remainingTime);
// 销毁定时器
int timer_destroy(Timer* timer);
#endif
#ifdef __cplusplus
}
#endif
timer.c :
#include "timer.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int timer_init(Timer* timer, TriggerType trigger_type, ...) {
memset(timer, 0, sizeof(Timer));
va_list args;
va_start(args, trigger_type);
struct sigevent sev;
struct sigaction sa;
memset(&sev, 0, sizeof(struct sigevent));
switch (trigger_type) {
case TRIGGER_SIGNAL:
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = va_arg(args, int); // 信号编号
sa.sa_sigaction =
va_arg(args, void (*)(int, siginfo_t*, void*)); // 信号处理函数
sev.sigev_value = va_arg(args, sigval_t); // 携带参数
// 注册定时器信号的处理函数
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
if (sigaction(sev.sigev_signo, &sa, NULL) == -1) {
perror("sigaction");
return -1;
}
break;
case TRIGGER_THREAD:
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function =
va_arg(args, void (*)(sigval_t)); // 线程触发时的处理函数
sev.sigev_value = va_arg(args, sigval_t); // 携带参数
break;
default:
va_end(args);
return -1;
}
va_end(args);
if (timer_create(CLOCK_MONOTONIC, &sev, &timer->timer_id) == -1) {
perror("timer_create");
return -1;
}
return 0;
}
int timer_start(Timer* timer, TimerInterval interval) {
timer->initial_value.it_value.tv_sec = interval.seconds;
timer->initial_value.it_value.tv_nsec = interval.nanoseconds;
timer->initial_value.it_interval.tv_sec = interval.seconds;
timer->initial_value.it_interval.tv_nsec = interval.nanoseconds;
if (timer_settime(timer->timer_id, 0, &timer->initial_value, NULL) == -1) {
perror("timer_settime");
return -1;
}
timer->status = TIMER_RUNNING;
return 0;
}
int timer_pause(Timer* timer) {
if (timer->status == TIMER_RUNNING) {
timer->status = TIMER_PAUSED;
struct itimerspec value;
memset(&value, 0, sizeof(struct itimerspec));
if (timer_settime(timer->timer_id, 0, &value, &timer->current_value) ==
-1) {
perror("timer_settime");
return -1;
}
}
return 0;
}
int timer_resume(Timer* timer) {
if (timer->status == TIMER_PAUSED) {
if (timer_settime(timer->timer_id, 0, &timer->current_value, NULL) == -1) {
perror("timer_settime");
return -1;
}
timer->status = TIMER_RUNNING;
}
return 0;
}
int timer_reset(Timer* timer) {
if (timer->status == TIMER_RUNNING || timer->status == TIMER_PAUSED) {
// 重新配置时间间隔为初始值
if (timer_settime(timer->timer_id, 0, &timer->initial_value, NULL) == -1) {
perror("timer_settime");
return -1;
}
}
return 0;
}
int timer_set_timeInterval(Timer* timer, TimerInterval interval) {
if (timer->status == TIMER_RUNNING) {
timer->initial_value.it_value.tv_sec = interval.seconds;
timer->initial_value.it_value.tv_nsec = interval.nanoseconds;
timer->initial_value.it_interval.tv_sec = interval.seconds;
timer->initial_value.it_interval.tv_nsec = interval.nanoseconds;
if (timer_settime(timer->timer_id, 0, &timer->initial_value, NULL) == -1) {
perror("timer_settime");
return -1;
}
}
return 0;
}
int timer_get_time(Timer* timer,
int* status,
TimerInterval* interval,
TimerInterval* remainingTime) {
struct itimerspec value;
status = timer->status;
if (timer_gettime(timer->timer_id, &value) == -1) {
perror("timer_gettime");
return -1;
}
// 时间间隔
interval->seconds = value.it_interval.tv_sec;
interval->nanoseconds = value.it_interval.tv_nsec;
// printf("it_interval: %ld.%09ld\n", value.it_interval.tv_sec,
// value.it_interval.tv_nsec);
// 获取剩余时间
remainingTime->seconds = value.it_value.tv_sec;
remainingTime->nanoseconds = value.it_value.tv_nsec;
// printf("it_value: %ld.%09ld\n", value.it_value.tv_sec,
// value.it_value.tv_nsec);
return 0;
}
// 销毁定时器
int timer_destroy(Timer* timer) {
if (timer_delete(timer->timer_id) == -1) {
perror("timer_delete");
return -1;
}
return 0;
}
测试:
#include <stdio.h>
#include <unistd.h>
#include "timer.h"
#define TIMER_SIGNAL SIGRTMIN + 5
#define TIMER_TRIGGER_TYPE 0
#if TIMER_TRIGGER_TYPE == 0
void timer_handler(int signum, siginfo_t* info, void* context) {
sigval_t data = info->si_value;
printf("Timer expired! signal trigger. Parameter values: %d\n", data.sival_int);
}
#else
void timer_handler(sigval_t data) {
printf("Timer expired! thread trigger. Parameter values: %d\n", data.sival_int);
}
#endif
int main() {
Timer timer;
sigval_t data;
TimerInterval value;
data.sival_int = 1024;
#if TIMER_TRIGGER_TYPE == 0
timer_init(&timer, TRIGGER_SIGNAL, TIMER_SIGNAL, timer_handler, data);
#else
timer_init(&timer, TRIGGER_THREAD, timer_handler, data);
#endif
value.seconds = 5;
value.nanoseconds = 0;
timer_start(&timer, value);
TimerInterval value_interval;
TimerInterval value_remainingTime;
while (1) {
sleep(1);
timer_get_time(&timer, &value_interval, &value_remainingTime);
printf("value_interval: %ld.%09ld\n", value_interval.seconds,
value_interval.nanoseconds);
printf("value_remainingTime: %ld.%09ld\n", value_remainingTime.seconds,
value_remainingTime.nanoseconds);
}
return 0;
}