您的位置:首页 > 其它

编写用户侧定时器

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

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

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

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

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

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

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

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

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

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

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

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

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

[cpp] view
plain copy

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);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: