是否可以使用QThread实现轮询而不进行子类化?

Tad*_*yan 3 c++ qt multithreading qthread

我有一个类,它是一些设备的抽象.

class Device  
{  
public:  
  ...  
  void Start();  
  void Stop();  
  void MsgLoop();

signals:
  void sMsgArrived();
}  
Run Code Online (Sandbox Code Playgroud)

从GUI线程调用Start()和Stop().Start()开始运行MsgLoop()的新线程.它看起来像这样:

void MsgLoop()  
{
   forever {  
      if(SUCCESS == ReadMsg()) //synchronous, non-blocking
      {
        ProcessMsg(); //quite fast
        emit sMsgArrived(); //this signal is connected with a slot in GUI thread  
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

当调用Stop()时,程序应该从MsgLoop()返回并停止该线程.如何在没有子类化的情况下使用QThread实现它?

Fik*_*tik 5

通常,您必须决定由谁来负责管理线程.它是设备还是主窗口?或者可能是一些设备管理员 在您的情况下,设备应该可以管理自己的线程,因此如果您不想将其子类化,请使用组合:

class Device : QObject
{
    Q_OBJECT
public:
    Device(QObject * parent = NULL);
    void Start();  
    void Stop();  

private slots:
    void MsgLoop();

signals:
    void sMsgArrived();

private:
    QThread thread;
    bool stopThread;
};


Device::Device(QObject * parent) : QObject(parent)
{
    moveToThread(&thread);
    connect(&thread, SIGNAL(started()), this, SLOT(MsgLoop()));
}

void Device::Start()
{
    stopThread = false;
    thread.start();
}

void Device::Stop()
{
    stopThread = true;
    thread.wait();      // if you want synchronous stop
}

void Device::MsgLoop()
{
  // your loop
  while(!stopThread)
    if(SUCCESS == ReadMsg())
    {
      ProcessMsg();
      emit sMsgArrived();
    }
  QThread::currentThread->quit();
}
Run Code Online (Sandbox Code Playgroud)

注意:线程停止仅在ReadMsg非阻塞时才起作用.如果你以后决定切换到阻塞读取(这可能适用于大多数情况),你将不得不找到另一种方法来阻止你的线程.