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

前提

  • 针对继承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();
      }
    

你可能感兴趣的:(QT)