加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 是否可以使用QThread实现轮询而无需对其进行子类化?

发布时间:2020-12-16 09:35:25 所属栏目:百科 来源:网络整理
导读:我有一个类,它是一些设备的抽象. class Device { public: ... void Start(); void Stop(); void MsgLoop();signals: void sMsgArrived();} 从GUI线程调用Start()和Stop(). Start()开始运行MsgLoop()的新线程.它看起来像这样: void MsgLoop() { forever { if
我有一个类,它是一些设备的抽象.

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

signals:
  void sMsgArrived();
}

从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  
      }
   }
}

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

解决方法

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

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确实是非阻塞的情况下,线程停止才有效.如果你以后决定切换到阻塞读取(这可能适用于大多数情况),你将不得不找到另一种方法来阻止你的线程.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读