首页 > 其他分享 >随想录(编写用户侧定时器)

随想录(编写用户侧定时器)

时间:2022-11-23 11:34:37浏览次数:54  
标签:node 定时器 name 随想录 TIMER timer 编写 struct


    定时器是我们在平时开发中经常使用到的工具,特别是在协议的编写上更是必不可少的组成部分。虽然系统本身给我们提供了定时器,但是有的时候,我们也想自己编写一个粗粒度的定时器,比如说在单元测试的时候。大家只要看到下面的实例代码,其实就会发现,只要利用一下sleep函数,编写属于自己的定时器原来不是一件复杂的事情。当然,在实现自己的定时器之前,你需要明白自己的定时器应该设计成什么样子?比如说,


    (1)定时器是否需要做互斥处理?

    (2)定时器支持那几种类型?

    (3)定时器支持的最大粒度是多少?有没有什么限制?

    (4)定时器的接口是什么?

    (5)定时器怎么遍历、组织和运行?


    下面的代码就是我自己练习时编写的一个定时器,具有下面几个特点:

    (1)支持1s为基本单位的定时操作;

    (2)支持定时器互斥操作,适合移植;

    (3)支持单次和循环两种定时器;

    (4)tick计数和定时函数处理是由不同线程完成;

    (5)定时器接口简单,和linux定时器接口基本一致。


    最后贴出自己的定时器代码,欢迎大家多提宝贵意见。

struct TIMER
{
int type;
int state;
int count;
int expire;
void (*func)(void*);
void* param;
struct LINK_NODE node;
char name[MAX_NAME_LEN];
};

#define MAX_NAME_LEN 16
#define TIMER_LOCK_INIT()
#define TIMER_LOCK(sem)
#define TIMER_UNLOCK(sem)

#define STATUS int
#define MAX_TIMER_VALUE (7*24*3600)

enum
{
SINGLE_SHOT = 1,
RECYCLE_TYPE = 2
};

enum
{
TIMER_ACTIVE = 1,
TIMER_NOT_ACTIVE = 2
};

static int g_timer_count;
static struct LINK_NODE g_timer_head;
static HANDLE h_timer_sem;

void timer_init()
{
g_timer_count = 0;
link_init(&g_timer_head);
h_timer_sem = TIMER_LOCK_INIT();
}

STATUS alloc_timer(const char* name, int type, int count, void (*func)(void*), void* param)
{
struct LINK_NODE* p_node;
struct TIMER* p_timer;

if(NULL == name || NULL == func || NULL == param)
{
return FALSE;
}

if(strlen(name) >= MAX_NAME_LEN)
{
return FALSE;
}

if(SINGLE_SHOT != type && RECYCLE_TYPE != type)
{
return FALSE;
}

if(MAX_TIMER_VALUE < count || 0 == count)
{
return FALSE;
}

TIMER_LOCK(h_timer_sem);
for(p_node = g_timer_head.next; NULL != p_node; p_node = p_node->next)
{
p_timer = GET_DATA_BY_ADDRESS(p_node, struct TIMER, node);
if(0 == strncmp(p_timer->name, name, strlen(name)))
{
TIMER_UNLOCK(h_timer_sem);
return FALSE;
}
}

p_timer = (struct TIMER*)malloc(sizeof(struct TIMER));
if(NULL == p_timer)
{
TIMER_UNLOCK(h_timer_sem);
return FALSE;
}

memset(p_timer, 0, sizeof(struct TIMER));
strncpy(p_timer->name, name, strlen(name));
p_timer->type = type;
p_timer->count = count;
p_timer->func = func;
p_timer->param = param;
p_timer->state = TIMER_NOT_ACTIVE;

add_node_into_link(&p_timer->node, &g_timer_head);
TIMER_UNLOCK(h_timer_sem);

return TRUE;
}


STATUS timer_start(const char* name)
{
struct LINK_NODE* p_node;
struct TIMER* p_timer;

if(NULL == name || strlen(name) >= MAX_NAME_LEN)
{
return FALSE;
}

TIMER_LOCK(h_timer_sem);
for(p_node = g_timer_head.next; NULL != p_node; p_node = p_node->next)
{
p_timer = GET_DATA_BY_ADDRESS(p_node, struct TIMER, node);
if(0 == strncmp(p_timer->name, name, strlen(name)))
{
break;
}
}

if(NULL == p_node)
{
TIMER_UNLOCK(h_timer_sem);
return FALSE;
}

if(TIMER_NOT_ACTIVE == p_timer->state)
{
p_timer->expire = g_timer_count + p_timer->count;
p_timer->state = TIMER_ACTIVE;
}

TIMER_UNLOCK(h_timer_sem);
return TRUE;
}


STATUS timer_del(const char* name)
{
struct LINK_NODE* p_node;
struct TIMER* p_timer;

if(NULL == name || strlen(name) >= MAX_NAME_LEN)
{
return FALSE;
}

TIMER_LOCK(h_timer_sem);
for(p_node = g_timer_head.next; NULL != p_node; p_node = p_node->next)
{
p_timer = GET_DATA_BY_ADDRESS(p_node, struct TIMER, node);
if(0 == strncmp(p_timer->name, name, strlen(name)))
{
break;
}
}

if(NULL == p_node)
{
TIMER_UNLOCK(h_timer_sem);
return FALSE;
}

delete_node_from_link(&p_timer->node);
TIMER_UNLOCK(h_timer_sem);
free(p_timer);
return TRUE;
}


void timer_run()
{
struct LINK_NODE* p_node;
struct TIMER* p_timer;
int count;

while(1)
{
count = g_timer_count;
TIMER_LOCK(h_timer_sem);
for(p_node = g_timer_head.next; NULL != p_node; p_node = p_node->next)
{
p_timer = GET_DATA_BY_ADDRESS(p_node, struct TIMER, node);
if(TIMER_ACTIVE == p_timer->state && count > p_timer->expire)
{
p_timer->func(p_timer->param);

if(SINGLE_SHOT == p_timer->type)
{
p_timer->state = TIMER_NOT_ACTIVE;
}
else
{
p_timer->expire = count + p_timer->count;
}
}
}

TIMER_UNLOCK(h_timer_sem);
sleep(1);
}
}


void tick_process()
{
while(1)
{
g_timer_count ++;
sleep(1);
}
}





标签:node,定时器,name,随想录,TIMER,timer,编写,struct
From: https://blog.51cto.com/feixiaoxing/5880707

相关文章

  • 随想录(为什么循环队列具有先天的并行性)
       循环队列是很多人喜欢用的一种数据结构。本着先来先服务的特性,循环队列是一种十分简单、健壮的数据结构。不像链表、二叉树,如果使用不慎,就会造成很大的麻烦,但是在循......
  • 随想录(linux下的pv操作)
         关于pv操作部分的内容,其实算不上什么新的东西。但是它对于我们理解信号量、消息处理部分的工作还是有很大帮助的。之前我们给出了一个win32的处理方案,但是实现的......
  • 随想录(写给那些学校不是985、211的同学们)
       每年的6、7月份都是一年一度的毕业季。按照某些新闻机构的统计数字来说,现在每一年毕业的人数达到了600万之多。然而随着社会经济的放缓、贫富差距的拉开,找工作变得越......
  • 随想录(用memmove函数代替strncpy函数)
        有过C语言编程的朋友应该都有过指针越界的困扰。不管越界的地方是全局地址、还是局部地址,查起来都是非常麻烦,原因大多时候都来自于自己对char数组类型的误用。很多......
  • 随想录(编写简单资源管理代码)
      不管编写什么软件,我们都会涉及到模块的编写。说是模块,其实就是管理一片资源,这些资源的概念很广,可以是内存、锁、socket、字符串、文件、空间大小等等。所以不管是什么......
  • 随想录(设计软件模块的接口)
       开发软件是一件复杂而且辛苦的工作,不同的模块之间的逻辑需要考虑,应用层与底层的关系也需要考虑。模块之间的关系处理不好,就会给软件的编写质量带来影响。当然不管软......
  • 随想录(矩阵计算的几种方法)
    【声明:版权所有,欢迎转载,请勿用于商业用途。】   要进行图像处理,矩阵运算是少不了的。不管是加减乘除,还是旋转、求逆、矩阵分解,都需要lib来好好支持。下面,主要就说一......
  • 随想录(机器学习的生产应用)
    【声明:版权所有,欢迎转载,请勿用于商业用途。     从范围上讲,人工智能>机器学习>模式识别。最近机器学习愈演愈烈,特别是深度学习的发展,极大的推动了机器学习的应......
  • 随想录(嵌入式工程师的出路)
    【声明:版权所有,欢迎转载,请勿用于商业用途。  嵌入式工程师分布在各行各业上面。这其中包括了消费电子、工业电子、汽车电子和军用电子等等。从功能上面看,嵌入式本身包......
  • 随想录(对比着c学java)
    【声明:版权所有,欢迎转载,请勿用于商业用途。  对于java,有两种论调。一种是鄙视,认为java是个人都能学,完全体现不出程序员的水平。还有一种,就是拔高java,认为java无所不能,j......