您的位置:首页 > 运维架构 > Linux

Linux下利用posix线程库设计自己的应用层timer定时器

2006-06-15 14:33 405 查看
用管了vxWorks下面的定时器转到Linux之后发现麻烦了很多,想想用posix的线程库可以实现自己的timer定时器,这样用起来就方便了很多,原理实际很简单,使用posix的conditional信号就可以了,不多说了,看代码吧就:

#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <signal.h>
#include <semaphore.h>
#include <sys/time.h>

#include "timerLib.h"

static struct TIMER_EVENT *ptimer_head = NULL;

void *timer_task_thread(void *args)
{
int ret;
time_t t;
struct TIMER_EVENT *ptimer;
pthread_t taskID;
struct timespec cond_time;
long sec;
long usec;

ptimer = (struct TIMER_EVENT *)args;

if (ptimer->timevalue > 1000000)
{
sec = (ptimer->timevalue/1000000);
usec = (ptimer->timevalue%1000000);
}
else
{
sec = 0;
usec = ptimer->timevalue;
}

taskID = pthread_self();
pthread_detach(taskID);
while(1)
{
time(&t);

cond_time.tv_sec = t+sec;
cond_time.tv_nsec = usec*1000;
ret = pthread_cond_timedwait(&ptimer->cond,&ptimer->mutex, &cond_time);
if (ret == 0)
{
if (ptimer->live == 0)
{
free(ptimer);
pthread_exit((void *)NULL);
}
}
else if (ret == ETIMEDOUT)
{
ptimer->func(ptimer->name);
}
pthread_mutex_unlock(&ptimer->mutex);
}
}

static void add_timer_tail(struct TIMER_EVENT *new)
{
struct TIMER_EVENT *ptemp;

assert(new != NULL);

if (ptimer_head == NULL)
{
new->prev=new->next = NULL;
ptimer_head = new;
return;
}

for(ptemp=ptimer_head; ptemp->next!=NULL; ptemp=ptemp->next);

ptemp->next = new;
new->prev = ptemp;
new->next = NULL;
}

void del_timer(TIMERID id)
{
struct TIMER_EVENT *ptemp;

for(ptemp=ptimer_head; ptemp!=NULL; ptemp=ptemp->next)
{

pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&(ptemp->mutex));
pthread_mutex_lock(&ptemp->mutex);
if (ptemp->id == id)
{
/* Delete header */
if (ptemp == ptimer_head)
{
if (ptemp->next != NULL)
{
ptemp->next->prev = NULL;
ptemp->live = 0;
ptimer_head = ptemp->next;
pthread_cond_signal(&ptemp->cond);
return;
}
else
{
ptemp->live = 0;
ptimer_head = NULL;
pthread_cond_signal(&ptemp->cond);
return;
}
}
else if (ptemp->next == NULL) /* delete tail */
{
ptemp->live = 0;
ptemp->prev->next = NULL;
pthread_cond_signal(&ptemp->cond);
return;
}
else /* normal */
{
ptemp->live = 0;
ptemp->prev = ptemp->next;
pthread_cond_signal(&ptemp->cond);
return;
}
}
pthread_cleanup_pop( 1 );
}
}

TIMERID add_timer(char *name, long timevalue, void *func)
{
struct TIMER_EVENT *ptimer;
pthread_t taskID;
int ret;
struct TIMER_EVENT *ptemp;
int dirty;

ptimer = (struct TIMER_EVENT *)malloc(sizeof(struct TIMER_EVENT));
if (ptimer == NULL)
{
return (-1);
}

pthread_mutex_init(&ptimer->mutex, NULL);
pthread_cond_init(&ptimer->cond, NULL);
ptimer->live = 1;
ptimer->func = func;
ptimer->timevalue = timevalue;
do {
ptimer->id = rand();
dirty = 0;
for(ptemp=ptimer_head; ptemp != NULL; ptemp=ptemp->next)
{
if( ptemp->id == ptimer->id)
{
dirty = 1;
break;
}
}

} while(dirty == 1);

if (name != NULL)
{
sprintf(ptimer->name, "%s", name);
}
else
{
sprintf(ptimer->name, "timer%d", ptimer->id);
}

ret = pthread_create(&taskID, 0, timer_task_thread, (void *)ptimer);
if (ret < 0)
{
perror("pthread_create");
free(ptimer);
return (-1);
}
add_timer_tail(ptimer);

return ptimer->id;
}

头文件定义: #ifndef __TIMER_LIB_H__ #define __TIMER_LIB_H__ typedef int TIMERID; struct TIMER_EVENT { struct TIMER_EVENT *prev, *next; TIMERID id; char name[64]; int live; pthread_mutex_t mutex; pthread_cond_t cond; long timevalue; void (*func)(void *args); }; /* Add a timer with name, timevalue(uSeconds) and handler */ TIMERID add_timer(char *name, long timevalue, void *func); /* Delete a timer with id */ void del_timer(TIMERID id); #endif /* __TIMER_LIB_H__ */ 测试主程序及编译Makefile: #include #include #include #include #include "timerLib.h" void timer_handler1(void) { printf("Hello timer.../n"); } void timer_handler2(void) { printf("Hello timer2222222222.../n"); } int main(int argc, char *argv[]) { TIMERID id1, id2; id1 = add_timer("test", 3000000, timer_handler1); id2 = add_timer("test1", 10000000, timer_handler2); for (;;) { switch(getchar()) { case 'l': case 'L': break; default: break; } } return 0; } Makefile: ##Timer library test CC=gcc C_FLAGS = -Wall -O2 LD_FLAGS = -lpthread all: test test: timerLib.o test.o $(CC) $^ $(LD_FLAGS) -o test timerLib.o: timerLib.c timerLib.h $(CC) $(C_FLAGS) -c timerLib.c test.o: test.c timerLib.h $(CC) $(C_FLAGS) -c test.c clean: rm -f *.o test
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: