控制多线程暂停、继续、退出

前提

针对继承QThread类,重写run接口方式创建的多线程

线程退出

  • 对于正在运行的线程,如果想要退出,QT5提供了封装好的接口:requestInterruption和isInterruptionRequested。不再需要自定义互斥量和bool类型的退出标记。
  • 退出之前调用requestInterruption,在线程内部的循环操作前判断isInterruptionRequested是否需要退出
  • 不要使用terminate接口,可能会引起未知错误
  • 配合调用quit和wait接口,使线程真正退出
  if (pThread->isRunning())
  {
  	pThread->requestInterruption();
  	pThread->quit();
  	pThread->wait();
  }

  void run()
  {
  	while(1)
  	{
  		if (this->isInterruptionRequested())
  		{
  			return;
  		}

  		// TODO
  	}
  }

线程暂停和继续

  • 使用自定义互斥量和bool类型的暂停标记
    • 定义两个互斥量,一个互斥量用于保护暂停标记,另一个用于保护具体操作
    • 暂停标记的保护可以使用互斥锁简化操作
  • 对外提供暂停、继续、是否暂停三个接口
    • 暂停接口修改暂停标记变量,内部循环前判断暂停变量值,如果需要暂停,则QWaitCondition的wait接口阻塞线程;
    • 继续接口修改暂停标记标记,同时使用QWaitCondition的wakeall接口唤醒所有等待的线程
    • 是否暂停接口可以让客户端知道当前线程是否处于暂停状态。
  • 暂停后如果想退出线程,必须先继续线程才能退出
  void Pause()
  {
  	QMutexLocker locker(&m_mutexPause);
  	m_bPaused = true;
  }

  void Resume()
  {
  	QMutexLocker locker(&m_mutexPause);
  	m_bPaused = false;
  	m_WaitCondition.wakeAll();
  }

  bool IsPaused()
  {
  	return m_bPaused;
  }

  void run()
  {
  	while(1)
  	{
  		m_mutexRun.lock();
  		if (m_bPaused)
  		{
  			m_WaitCondition.wait(&m_mutexRun);
  		}

  		// TODO

  		m_mutexRun.unlock();
  	}
  }
  
  if (pThread->isRunning())
  {
  	if (pThread->IsPaused())
  	{
  		pThread->Resume();
  	}

  	pThread->requestInterruption();
  	pThread->quit();
  	pThread->wait();
  }

上一篇:Date数据占位符定义


下一篇:问题 F: 支教大学生鲁甸地震中的坚守