当前位置: 首页 > 工具软件 > QuteCom > 使用案例 >

qutecom笔记-thread类

许照
2023-12-01

Thread以组合方式扩展了boost::thread

事件队列的实现和事件传递部分的代码很巧妙。

扩展了以下功能:
1、线程消息队列
2、线程删除自身
3、sleep

1、线程消息队列的实现方式:
void Thread::runEvents() {
 RecursiveMutex::ScopedLock scopedLock(_threadMutex);

 while (true) {
  while (!_eventQueue.empty()) {//处理所有入栈事件
   IThreadEvent *event = _eventQueue.front();
   _eventQueue.pop();

   scopedLock.unlock();//保护_eventQueue,在取出后,事件可以继续入队列。
   event->callback();//处理事件
   OWSAFE_DELETE(event);//释放事件
   scopedLock.lock();//保护_eventQueue,不允许操作_eventQueue
  }

  //所有事件已经处理完毕
  if (_terminate) {
   return;
  }
  //继续等待事件_threadMutex必须已经lock,进入等待后_threadMutex被自动unlock
  _threadCondition.wait(scopedLock);//_threadMutex
  //当wait返回时,_threadMutex上的锁会重新加上
 }
}

_eventQueue即为消息队列
传递消息的函数postEvent
注意参数为IThreadEvent,内含一个回调函数callback

当一个线程向Thread类型的线程传递事件时,需要把处理该事件的函数一并传递给目标线程。
这样做的直接目的就是在目标线程内调用该函数对象。即在void Thread::runEvents()内的event->callback();调用之。

关于IThreadEvent在后面说明。先说明消息队列的具体实现。
void Thread::runEvents()内
取出一个事件:
IThreadEvent *event = _eventQueue.front();
_eventQueue.pop();
处理一个事件:
event->callback();
OWSAFE_DELETE(event);//释放事件占用的堆空间。
等待一个事件:
_threadCondition.wait(scopedLock);
传递消息的函数postEvent的说明:
void Thread::postEvent(IThreadEvent * event) {
 //自动锁,构造时_threadMutex.lock析构时_threadMutex.unlock
 RecursiveMutex::ScopedLock scopedLock(_threadMutex);
 //事件入队列
 _eventQueue.push(event);
 //手动为_threadMutex解锁,runEvents内_threadCondition wait一个RecursiveMutex::ScopedLock对象。该对象以_threadMutex构造。
 scopedLock.unlock(); 
 _threadCondition.notify_all();//唤醒在_threadCondition上wait的所有线程(实际只有本线程)。
}

注意scopedLock.unlock()之后,在postEvent时不会再次调用unlock

原因见scoped_lock的析构函数 ~scoped_lock()
如下:
explicit scoped_lock(Mutex& mx, bool initially_locked=true)
        : m_mutex(mx), m_locked(false)
{
   if (initially_locked) lock();
}
~scoped_lock()
{
   if (m_locked) unlock();
}

void lock()
{
   if (m_locked) throw lock_error();
   lock_ops<Mutex>::lock(m_mutex);
   m_locked = true;
}
void unlock()
{
   if (!m_locked) throw lock_error();
   lock_ops<Mutex>::unlock(m_mutex);
   m_locked = false;
}
scoped_lock内部记录了m_locked的状态,因此当手动unlock后,该对象析构后不再unlock

关于boost::condition
condition是一个简单的同步对象,用于使一个线程等待一个特定的条件成立(比如
资源可用)。一个condition对象总是和一个lock对象配合使用。wait系列函数调用后,
必须已经通过lock对象加上了锁。当线程陷入等待时,condtion
对象将释放lock对象上的锁,当wait返回时,lock对象上的锁会重新加上,
这一unlock/lock动作由conditon对象自动完成。


2、删除自身

声明:
Thread.h:

public:
 /**
  * Defines whether the thread should delete itself at end.
  */
 OWTHREAD_API void setAutoDelete(bool);

 /**
  * Returns true if the thread will autodelete itself.
  */
 OWTHREAD_API bool getAutoDelete() const;
protect:
  /**
  * If set to true, the class will automatically delete itself when run()
  * returns.
  * default is false.
  */
 bool _autoDelete;

Thread.cpp实现删除自身的代码:

runThread是一个线程启动代理函数,调用了虚函数run(),run即为线程函数。
void Thread::runThread() {
 {
  RecursiveMutex::ScopedLock scopedLock(_threadMutex);
  _threadRunning = true;
 }

 if(_terminate == true)//线程对象未启动已被删除
 {
  printf("==##[error]thd del before actually running!##==/n");
  return;
 }

 run();

 bool autoDelete;
 {
  RecursiveMutex::ScopedLock scopedLock(_threadMutex);
  _threadRunning = false;
  autoDelete = _autoDelete;
 }

 if (autoDelete) {//这里实现自删除
  delete this;
 }
}

 类似资料: