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 == EINTR);
gettimeofday(&end,0);
delay = (end.tv_sec - start.tv_sec) * 1000;
delay += (end.tv_usec - start.tv_usec);
pthread_mutex_lock(&manage->workmutex);
LIST_FOREACH(item, &(manage->list_), entry_) {
//printf("m_data = %d m_counter = %d ",item->m_data,item->m_counter);
if ( item->m_counter < delay)
item->m_counter = 0;
else
item->m_counter -= delay;
//printf("m_data = %d m_counter = %d\n",item->m_data,item->m_counter);
if (item->m_counter == 0) {
if (item->m_func)
item->m_func(item->m_data);
manage->remove_timer_unsafe(item);
item->m_state = Timer::TIMER_TIMEOUT;
}
}
pthread_mutex_unlock(&manage->workmutex);
}
}
void TimerManager::add_timer(Timer* vtimer) {
pthread_mutex_lock(&workmutex);
LIST_INSERT_HEAD(&(this->list_),vtimer,entry_);
pthread_mutex_unlock(&workmutex);
}
void TimerManager::remove_timer(Timer* vtimer) {
pthread_mutex_lock(&workmutex);
LIST_REMOVE(vtimer, entry_);
pthread_mutex_unlock(&workmutex);
}
void TimerManager::add_timer_unsafe(Timer* vtimer) {
LIST_INSERT_HEAD(&(this->list_),vtimer,entry_);
}
void TimerManager::remove_timer_unsafe(Timer* vtimer) {
LIST_REMOVE(vtimer, entry_);
}
还有一个类的代码先不上传,这是我们正在学的Linux一个实验,上传的话万人都交这个代码给老师了。
三、总结:
1、按照之前我写代码的习惯,都是先声明一个类A,,接着依次实现A的方法,然后再声明一个类B,接着依次实现B的方法。
按照这个习惯,如果类A在类B的前面声明,如果类A要调用类B中的方法,就必须在定义之前声明class A,class B,接着把类A声明为类B的友元类,还要把实现放在两个类定义的后面,才不会出错。
按照这个习惯,如果类A要调用类B的方法,类B要调用A的方法,这个要怎么办?到底哪个类放在前面?和上面的情况相似。我们一定要保证某个类在调用另一个类的对象,另一个类的方法都已经实现。否则会出现类似invalid use of incomplete type ‘struct Timer’这样的错误。
2、当类中声明了静态变量,而且未初始化。这时候要在类外单独再声明一次静态变量,这样系统会自动给这些变量分配全局内存空间。这样,后面就可以放心地对静态变量进行赋值了。不然会出现类似于undefined reference to `TimerManager::m_instance'这样的错误。
3、程序中出现了死锁,process中用lock和unlock锁起一段代码,而这段代码中又有用lock和unlock锁起一段断码,这样后一段代码无法执行切程序处于挂起等待状态。
4、我的实现是通过select不断的检查时间,可是select这个函数调用占用了一些时间导致精度误差。如果我尽量少调用select函数,那么实时性不够,如果调用次数很多,那么精确度又不够。在我的代码中折中,选取1s作为调用select的间隔。