是否可以在不继承 QThread 的情况下实现轮询? [英] Is it possible to implement polling with QThread without subclassing it?

查看:68
本文介绍了是否可以在不继承 QThread 的情况下实现轮询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class, which is an abstraction of some device.

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

signals:
  void sMsgArrived();
}  

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

Start() and Stop() are called from GUI thread. Start() begins new thread, which runs MsgLoop(). It looks like this:

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

当 Stop() 被调用时,程序应该从 MsgLoop() 返回并停止线程.如何在不继承 QThread 的情况下实现它?

When Stop() is called, program should return from MsgLoop() and stop the thread. How can I implement this with QThread without subclassing it?

推荐答案

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

Generally you have to decide who will be responsible for managing the thread. Is it the Device or the main window? Or possibly some device manager. In your case the Device should probably manage its own thread, so if you don't want to subclass it, use composition:

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();
}

注意:只有 ReadMsg 确实是非阻塞的,线程停止才会起作用.如果您稍后决定切换到阻塞读取(这可能适用于大多数情况),您将不得不想出另一种方法来停止您的线程.

NOTE: the thread stopping will only work if ReadMsg really is non-blocking. If you later decide to switch to blocking read (and that would probably be appropriate for most cases), you will have to figure out another way how to stop your thread.

这篇关于是否可以在不继承 QThread 的情况下实现轮询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆