c++ - QThread 对象作为 worker 类的成员

标签 c++ qt qthread

我读过很多文章,关于为什么子类化 QThread 在大多数情况下不是一个好主意,以及如何正确使用 QThread,调用 moveToThread 方法。 Here我们可以看到这种设计的一个典型例子。

我设计的类应该满足以下要求:

  • 它想使用信号和槽,所以我需要一个事件循环,并将使用 moveToThread

  • 它将仅公开带有信号和插槽的接口(interface)。没有普通的 C++ 方法。

  • 所有插槽都应在对象的专用线程中执行,每个对象一个线程。因此线程应该在创建对象时创建,并且应该在对象死亡时结束。

于是想到一个明显的解决方案(未经测试,只是一个草图代码):

class Worker : public QObject {
Q_OBJECT

public:
    Worker() {
        thread = new QThread();
        // ...Some signal-slot connections may be done here...
        // ...Some other connections may be performed by user code...
        moveToThread(thread);
        thread->start();
    }

    ~Worker() {
        thread->exit();
        thread->wait();
        delete thread;
    }

public slots:
    void process(); // and other interface slots

signals:
    // Interface signals

private:
    QThread* thread;
};

所以重点是将 QThread 对象声明为工作类的(私有(private))成员,但我从未在任何示例或其他人的代码中看到过。

所以我想知道这个设计是不是有缺陷?它是否有一些我没有注意到的致命缺点?还是没关系,只是不经常需要?

最佳答案

只要您将对象移出工作线程,这是可能的。以下是您可能会这样做的方法 - 请注意,您应该按值持有线程,没有必要不使用编译器为您管理内存。

class Worker : public QObject {
  Q_OBJECT
  QThread m_thread;
public:
  Worker() {
    m_thread.start();
    moveToThread(&m_thread);
  }
  ~Worker() {
    // Move us out of any thread.
    // moveToThread must always be called from QObject::thread()!
    {
      QObject sig;
      sig.connect(&sig, &QObject::destroyed, this, [this]{
        this->moveToThread(0); // become thread-less
        m_thread->quit();
      });
    }
    // Wait for the thread to stop
    m_thread.wait();
  }
};

鉴于可以通过QtConcurrent::run 异步完成工作,您很可能无论如何都不应该使用这样的对象。最有可能的是,您将浪费大部分空闲的线程,因为您不太可能始终保持线程可运行。不可运行的线程本质上是一种浪费的资源。

关于c++ - QThread 对象作为 worker 类的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36403955/

相关文章:

c++ - 如何将可变数量的参数传递给 lambda 函数

c++ - 使用 boost 处理 COM 变体

c++ - Cpp Pantheios 日志库,调试断言失败错误

c++ - SIMD 代码?

css - QComboBox 样式表左边距没有副作用

c++ - 计时器是否从另一个线程启动?

python - pyqtgraph ImageView 在多线程时卡住

c++ - Qt C++ : Connecting value changing in two spinboxes

c++ - 塞类模拟键盘输入

python - 为什么 PyQt 在没有信息的情况下崩溃? (退出代码 0xC0000409)