- 论坛徽章:
- 0
|
一、问题
近日在学习Linux的开发中,遇到需要使用计时的情况,而且是为线程计时,具体说就是让一个线程等待一定时间,然后继续执行,但没有找到这样的系统函数;而且有时候需要让一个线程在从某个时刻开始的指定时间段过后进行相关的处理,像alarm这样的定时给进程发信号的方式是给进程发信号,不能准确地给任意一个线程计时,特别是当有多个线程同时都要计时的时候。总希望能有一个方便的计时器给线程计时。考虑到线程间通信中的一个条件等待函数pthread_cond_wait()可以让线程阻塞,而一个相似的函数pthread_cond_timedwait()可以让线程阻塞指定的时间,可能可以作为一个计时器。下面我写了一个简单的计时器类Timer。
二、实现Timer类
- Timer类的声明
class Timer
{
public:
/* user 是使用该计时器的用户类的对象指针 */
Timer(UserClass *user);
~Timer();
/* set timer's expire period */
void setLen(int len) { m_len = len; }
/* get timer's expire period */
int getLen() { return m_len; }
/* start this timer */
void start();
/* stop this timer */
void stop();
/* process timer expire message */
void expire();
/* thread function used to run timing */
static void *timerThread(void *arg);
/* get a thread mutex */
pthread_mutex_t &getMutex() { return m_mutex; }
/* get a pthread condition */
pthread_cond_t &getCond() { return m_cond; }
private:
enum TIMER_STATUS
{
TIMER_IDLE,
TIMER_STARTED,
};
int m_len;
int m_state;
UserClass *m_user;
pthread_cond_t m_cond;
pthread_mutex_t m_mutex;
};
- Timer类的定义
Timer::Timer(UserClass *user): m_user(user)
{
m_state = TIMER_IDLE;
pthread_mutex_init(&m_mutex, NULL);
pthread_cond_init(&m_cond, NULL);
}
Timer::~Timer()
{
pthread_cond_destroy(&m_cond);
pthread_mutex_destroy(&m_mutex);
}
void Timer::start()
{
if (TIMER_IDLE != m_state)
{
return;
}
pthread_t timerThrd;
/*
* 创建一个线程用于计时,因为类的成员函数作为线程函数必须是静态函数,
* 给线程传递的参数是该计时器的对象的指针,用于获得计时器对象的信息
*/
if (0 != pthread_create(&timerThrd, NULL, &timerThread, (void *) this))
{
cout "create timer thread fail !" endl;
return;
}
}
void Timer::stop()
{
if (TIMER_IDLE == m_state)
{
return;
}
else
{
pthread_mutex_lock(&m_mutex);
// 在超时前可以停止该计时器
pthread_cond_signal(&m_cond);
pthread_mutex_unlock(&m_mutex);
m_state = TIMER_IDLE;
}
}
void Timer::expire()
{
m_state = TIMER_IDLE;
// 使用该计时器的用户进行相关的处理
m_user->expire();
}
void *Timer::timerThread(void *arg)
{
Timer *timer = (Timer *) arg;
int ret;
struct timespec timeout;
time_t now;
time(&now);
timeout.tv_sec = now + timer->getLen();
timeout.tv_nsec = 0;
pthread_mutex_lock(&timer->getMutex());
timer->m_state = TIMER_STARTED;
// 线程阻塞,开始等待
ret = pthread_cond_timedwait(&timer->getCond(), &timer->getMutex(), &timeout);
pthread_mutex_unlock(&timer->getMutex());
// 因为超时而线程解除阻塞
if (ETIMEDOUT == ret)
{
timer->expire();
}
return 0;
}
三、说明
该计时器只能同时被一个线程使用,如果要给多个线程计时,必须创建多个Timer对象,但一个对象可以被重复使用,而且接口相对友好,使用时只需setLen(), 然后start(),必要时可以stop(),计时完毕后用于计时的线程会自动退出。
本人刚学Linux开发不久,了解的也不多,如果有达人知道能让线程阻塞指定时间的函数,或者Linux中本来就有专门用于计时的系统调用,还望告知,我就不用费这劲了,谢谢!
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/33444/showart_393735.html |
|