日期:2014-05-16 浏览次数:20880 次
一、功能:
编写一个程序库,实现定时器的功能,它能为用户提供在同一进程中多次使用的定时器。
二、实现
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/queue.h> #include <sys/time.h> #include <pthread.h> #include <errno.h> #define DEFAULT_INTERVAL 1 int TIMER_CNT = 0; class Timer; //定时器 class TimerManager; //定时器管理器 class TimerManager { friend class Timer; //友元类,Timer类可分享此类的方法 public: typedef enum { TIMER_MANAGER_STOP=0, TIMER_MANAGER_START }TimerManagerState; static TimerManager *instance(); //当前实例 void start(); //启动当前线程,运行process函数 void stop(); //终止当前线程 void dump(); //清理当前剩下的无用定时器 void add_timer(Timer *vtimer); //线程安全的增加定时器 void remove_timer(Timer *vtimer); //线程安全的移除定时器 protected: static void *process(void *); private: TimerManager(); void add_timer_unsafe(Timer *vtimer); //线程非安全的增加定时器,本类使用 void remove_timer_unsafe(Timer *vtimer);//线程非安全的移除定时器,本类使用 static TimerManager *m_instance; static pthread_mutex_t workmutex; TimerManagerState m_state; LIST_HEAD(,Timer) list_; //链表头 static int mark; }; class Timer { friend class TimerManager; public: typedef enum { TIMER_IDLE = 0, TIMER_ALIVE, TIMER_TIMEOUT }TimerState; Timer(int vinterval,void (*vfunc)(void *),void *vdata); void start(); //把自己添加进定时器管理器的链表里 void stop(); //把自己从定时器管理器的链表里移除 void reset(int vinterval); //重置 ~Timer(); private: int id; //当前定时器的ID int m_interval; //定时器的定时时间,单位为秒 int m_counter; //还剩下多少时间,单位为微秒 TimerState m_state; //当前定时器的状态 void (*m_func)(void *); void *m_data; LIST_ENTRY(Timer) entry_; //当前定时器在链表中的地址 }; TimerManager *TimerManager::m_instance; pthread_mutex_t TimerManager::workmutex; TimerManager::TimerManager() { pthread_mutex_init(&workmutex,NULL); } TimerManager *TimerManager::instance() { if (m_instance == NULL) { pthread_mutex_lock(&workmutex); if (m_instance == NULL) m_instance = new TimerManager(); pthread_mutex_unlock(&workmutex); } return m_instance; } void TimerManager::start() { if (m_state == TIMER_MANAGER_STOP) { m_state = TIMER_MANAGER_START; pthread_t pid; int res = pthread_create(&pid,NULL,process,this); if (res != 0) { printf("pthread_create is failed\n"); exit(EXIT_FAILURE); } } } void TimerManager::stop() { this->m_state = TIMER_MANAGER_STOP; } void TimerManager::dump() { Timer *item; pthread_mutex_lock(&workmutex); LIST_FOREACH(item,&(this->list_),entry_) { if (item->m_counter == 0) { printf("Timer%d will be dumped!\n",(int)item->m_data); item->stop(); } } pthread_mutex_unlock(&workmutex); } void *TimerManager::process(void *arg) { pthread_detach(pthread_self()); TimerManager *manage = (TimerManager *)arg; Timer *item; struct timeval start,end; int delay; struct timeval tm; gettimeofday(&end,0); while (manage->m_state == TIMER_MANAGER_START) { tm.tv_sec = 0; tm.tv_usec = DEFAULT_INTERVAL * 1000; start.tv_sec = end.tv_sec; start.tv_usec = end.tv_usec; while (select(0,0,0,0,&tm) < 0 && errno