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
java timer 序列化_编程达人 应用层timer_如何序列化timer相关推荐
- java timertask 初始化_定时器实现方式之TimerTask、Timer
在未来某个指定的时间点或者经过一段时间延迟后执行某个事件,这时候就需要用到定时器了.定时器的实现方式有很多种,今天总结最简单的实现方式.java 1.3引入了定时器框架,用于在定时器上下文中控制线程的 ...
- vc 控制台添加托盘显示_编程达人
看到火哥给他的程序加上了系统托盘,我的没有很是不爽.于是花了几分钟找了些资料,给自己的也加上了系统托盘.现在将我的实现步骤分享一下. 先来解释下什么是系统托盘:其实准确的说法应该是任务栏通知区域.系统 ...
- java 面试 概率论_编程培训-115个Java面试题和答案B.pdf
编程培训-115个Java面试题和答案B.pdf "玩转"Java系列 1 题目115个Java面试题和答案终极(下) 第一篇讨论了面向对象编程和它的特点,关于Java和它的功能的 ...
- c和java哪个好学_编程入门学习c++和Java哪个比较好
编程入门学习c++和Java哪个比较好 发布时间:2020-04-25 16:54:41 来源:亿速云 阅读:231 作者:栢白 编程入门学习c++和Java哪个比较好?如今这些都是小白比较关心的,如 ...
- java webservice 线程_编程实践笔记{Java 线程 并发处理 Webservice}
1,保证线程安全的三种方法: a,不要跨线程访问共享变量 b,使共享变量是final类型的 c,将共享变量的操作加上同步 2,一开始就将类设计成线程安全的, 比在后期重新修复它,更容易. 3, 编写多 ...
- java请求注释_求达人给java代码【注释】!!请求尽量详细,万分感谢!!
(1)定义一个接口Inf,含有常量π和一个实现计算功能的方法calculate(),再分别定义一个面积类area和一个周长类circumference,各自按计算圆面积和圆周长具体实现接口中的方法,并 ...
- java 电梯算法_编程之美之小飞的电梯调度算法(多种解法)---Java语言
1.题目情景 我们假设都是从一楼上电梯的,而至于讯电梯停在其中的某一层.即所有的乘客都从一楼上电梯,到达某层之后,电梯停下来,所有乘客再从这里爬楼梯到自己的目的层.在一楼的时候,每个乘客选择自己的目的 ...
- delphi java jni 互通_编程应用实例:Java通过JNI与Delphi交互
来源: 赛迪网 作者: 若水 2008-05-14/18:11 前一段时间,我用java开发一个安装程序,适用于tomcat mysql构建的web环境.在开发的过程中遇到与写注册表,注册系统服务等问 ...
- Java国际化教程_编程入门自学教程_菜鸟教程-免费教程分享
教程简介 Java国际化入门教程 - 从简单的步骤了解Java国际化从基本到高级概念,包括概述,环境设置,区域设置,区域设置详细信息,显示语言,ResourceBundle,NumberFormat, ...
最新文章
- 6 redhat 查看rtc时间_RTC 月度小报 9 月 | WebRTC M77、RTC大会即将开幕、实时码流加速...
- Linux shell编程学习笔记-----第十六章
- jquery.dataTables.min.js:62 Uncaught TypeError: Cannot read property ‘style‘ of undefined原因
- 应邀ITGeGe在线教育社区嵌入式基础开发讲师
- day08.4-samba共享网盘服务
- .o文件 linux生成,vmlinux.o 生成
- 比较两个字符数组是否相等_Java比较两个数组是否相等(equals())
- 232.栈实现队列(力扣leetcode) 博主可答疑该问题
- PADS2007教程(二)——PCB封装
- PBRT的scene.pbrt使用方法
- 基于SpringBoot+SpringSecurity+JWT+RSA加密算法签名 Auth权限认证搭建教程
- Java char类型介绍
- 搜狐财报:年度盈利,长跑依旧
- 记一个vue v-if引起的图片加载导致样式跳动问题
- 打印1000年到2000年之间的闰年
- java符号三角形问题_实验四 回溯算法和分支限界法 符号三角形问题
- 创新突破,索爱S5耳机实现空间音频和动态头部跟踪
- 台式机和笔记本属于什么计算机,pc机属于什么型计算机
- GDOI2017游记
- ajax中Uncaught (in promise) TypeError: Failed to execute ‘setRequestHeader‘ on ‘XMLHttpRequest‘: Stri