java timer 序列化_编程达人 应用层timer_如何序列化timer

本文摘自    https://www.cnblogs.com/embedded-linux/p/9093990.html

应用层使用timer可以启动多个timer(每个timer管理一个目标时间),也可启用一个timer来管理多个目标时间。

多个timer时每个timer占用一部分空间,且存在多个timer同时到期的先后顺序问题(未多考虑,是否有问题待确定),可采用单个timer管理程序所有定时事件,即如何实现序列化的timer。

涉及到链表(记录多个目标时间的到期时间),信号处理函数(在SIG_ALAM函数中处理timer事件,并启动下一个timer时间点)。

#include

#include

#include

#include

#include

#include

#include

#include "list.h"

#define TIMERID_FIRST 100

typedef void (*stimer_func)(void *arg);

struct signal_timer{

struct list_head list_timer;

int id;

struct timeval itv;

struct timeval atv;

stimer_func stimer_handler;

void *arg;

};

int g_id;

struct list_head g_signal_list;

void alarm_handler(int sig);

int timer_init(void);

void timer_destroy(void);

// Return: id >0, in case of success; -1 in case of error.

int timer_add(long sec, long usec, void (*stimer_func)(void *arg), void *arg);

void timer_del(int id, int is_free);

static long long diff_time(struct timeval *t1, struct timeval *t2)

{

long long t1_usec = (t1->tv_sec * 1000 * 1000 + t1->tv_usec);

long long t2_usec = (t2->tv_sec * 1000 * 1000 + t2->tv_usec);

return (t1_usec - t2_usec);

}

static int max_time(struct timeval *t1, struct timeval *t2)

{

if(t1->tv_sec < t2->tv_sec){

return -1;

} else if(t1->tv_sec > t2->tv_sec){

return 1;

} else {

if(t1->tv_usec < t2->tv_usec){

return -1;

} else if(t1->tv_usec > t2->tv_usec){

return 1;

} else {

return 0;

}

}

}

#define min_time(t1, t2) (((t1).tv_sec < (t2).tv_sec) || \

(((t1).tv_sec == (t2).tv_sec) && \

((t1).tv_usec < (t2).tv_usec)))

#define MAX_USEC 999999

#define TV_MINUS(t1, t2, target) if((t1).tv_usec >= (t2).tv_usec){ \

(target).tv_sec = (t1).tv_sec - (t2).tv_sec;\

(target).tv_usec = (t1).tv_usec - (t2).tv_usec;\

} else { \

(target).tv_sec = (t1).tv_sec - (t2).tv_sec - 1;\

(target).tv_usec = (t1).tv_usec + (MAX_USEC - (t2).tv_usec);\

}

void alarm_handler(int sig)

{

struct timespec ts;

struct timeval tv;

struct timeval tv_min, *ptv_min;

struct itimerval it;

struct signal_timer *pstimer = NULL, *next= NULL;

int ret = 0;

if(list_empty(&g_signal_list))

return ;

// pstimer = list_first_entry(&g_signal_list, struct signal_timer, list_timer);

// ptv_min = &(pstimer->atv);

ptv_min = &tv_min;

clock_gettime(CLOCK_MONOTONIC_RAW, &ts);

tv.tv_sec = ts.tv_sec;

tv.tv_usec = ts.tv_nsec / 1000;

// printf("now time: %ld:%ld\n", tv.tv_sec, tv.tv_usec);

tv_min = tv;

tv_min.tv_sec += 1000; //default 1000s once

// two methods: sequence the timer list in case of more timers,

// not sequence in case of fewer timers.

list_for_each_entry_safe(pstimer, next, &g_signal_list, list_timer){

// printf("timerid:%d, aim time: %ld:%ld\n", pstimer->id, pstimer->atv.tv_sec, pstimer->atv.tv_usec);

if(max_time(&pstimer->atv, &tv) <= 0){

if(pstimer->stimer_handler != NULL){

pstimer->stimer_handler(pstimer->arg);

}

// only operation once, when overflow more times.

do{

pstimer->atv.tv_sec += pstimer->itv.tv_sec;

pstimer->atv.tv_usec += pstimer->itv.tv_usec;

} while(max_time(&pstimer->atv, &tv) < 0);

// } else {

// break;

}

// get next itimer

if(min_time(pstimer->atv, *ptv_min)){

ptv_min = &(pstimer->atv);

}

}

memset(&it, 0, sizeof(it));

// it.it_value.tv_sec = ptv_min->tv_sec - tv.tv_sec;

// it.it_value.tv_usec = ptv_min->tv_usec - tv.tv_usec;

TV_MINUS(*ptv_min, tv, it.it_value);

ret = setitimer(ITIMER_REAL, &it, NULL);

if(ret < 0){

perror("setitimer");

}

printf("process SIGALRM, next time is %ld:%ld\n", it.it_value.tv_sec, it.it_value.tv_usec);

}

int timer_add(long sec, long usec, void (*stimer_func)(void *arg), void *arg)

{

struct signal_timer *pstimer = (struct signal_timer*)malloc(sizeof(struct signal_timer));

struct timespec ts;

memset(pstimer, 0, sizeof(*pstimer));

pstimer->id = g_id++;

pstimer->itv.tv_sec = sec;

pstimer->itv.tv_usec = usec;

pstimer->stimer_handler = stimer_func;

if(arg){

pstimer->arg = arg;

}else {

pstimer->arg = pstimer;

}

list_add(&(pstimer->list_timer), &g_signal_list);

clock_gettime(CLOCK_MONOTONIC_RAW, &ts);

pstimer->atv.tv_sec += ts.tv_sec;

pstimer->atv.tv_usec += ts.tv_nsec / 1000;

return pstimer->id;

}

void timer_del(int id, int is_free)

{

struct signal_timer *pstimer = NULL;

list_for_each_entry(pstimer, &g_signal_list, list_timer){

if(pstimer->id == id){

list_del(&(pstimer->list_timer));

printf("----delete timerid is %d\n", pstimer->id);

if(is_free){

free(pstimer);

}

break;

}

}

}

int timer_init(void)

{

INIT_LIST_HEAD(&g_signal_list);

struct sigaction act;

int ret = 0;

// memset(&act, 0, sizeof(act));

sigemptyset(&act.sa_mask);

act.sa_handler = alarm_handler;

act.sa_flags = 0;

ret = sigaction(SIGALRM, &act, NULL);

if(ret < 0){

perror("sigaction");

return -1;

}

g_id = TIMERID_FIRST ;

return 0;

}

void timer_destroy(void)

{

struct signal_timer *pstimer = NULL;

while(! list_empty((&g_signal_list)->next)){

list_del((&g_signal_list)->next);

pstimer = container_of((&g_signal_list)->next, struct signal_timer, list_timer);

free(pstimer);

}

}

void timer_printf(void *arg)

{

if(arg){

struct signal_timer *pstimer = (struct signal_timer*)arg;

printf("timerid:%d, aim time: %ld:%ld\n", pstimer->id, pstimer->atv.tv_sec, pstimer->atv.tv_usec);

} else {

printf("timerid is %d\n", g_id);

}

}

int main(int argc, char **argv)

{

int tid1 = 0, tid2 = 0, tid3 = 0;

int i = 0;

signal(SIGPIPE, SIG_IGN);

timer_init();

tid1 = timer_add(2, 0, timer_printf, NULL);

tid2 = timer_add(3, 0, timer_printf, NULL);

tid3 = timer_add(5, 0, timer_printf, NULL);

alarm(1);

while(1){

sleep(1);

printf("sleep 1s\n");

i++;

if(i%3 == 0) timer_del(tid1, true);

if(i%7 == 0) timer_del(tid2, true);

if(i%9 == 0) timer_del(tid3, true);

}

timer_destroy();

return 0;

}

运行:

timerid:102, aim time: 468486:907381

timerid:101, aim time: 468486:907380

timerid:100, aim time: 468486:907380

process SIGALRM, next time is 0:999678

sleep 1s

timerid:100, aim time: 468488:907380

process SIGALRM, next time is 0:998577

sleep 1s

timerid:101, aim time: 468489:907380

process SIGALRM, next time is 0:999371

sleep 1s

----delete timerid is 100

process SIGALRM, next time is 0:999003

sleep 1s

timerid:102, aim time: 468491:907381

process SIGALRM, next time is 0:998901

sleep 1s

timerid:101, aim time: 468492:907380

process SIGALRM, next time is 2:998319

sleep 1s

sleep 1s

----delete timerid is 101

sleep 1s

process SIGALRM, next time is 0:999768

sleep 1s

----delete timerid is 102

sleep 1s

sleep 1s

sleep 1s

sleep 1s

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值