QThread对象作为辅助类的成员
QThread object as a member of worker class
我读过很多关于为什么在大多数情况下子类化QThread
是个坏主意的文章,以及如何正确使用QThread
,调用moveToThread
方法。在这里我们可以看到这样一个设计的典型例子。
我正在设计的课程应该满足以下要求:
-
它想要使用信号和插槽,所以我需要一个事件循环,并将使用
moveToThread
。 -
它将只显示带有信号和插槽的接口。没有普通的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
对象声明为worker类的(私有)成员,但我从未在任何示例或其他人的代码中见过这种情况。
这就是为什么我怀疑这个设计是否有缺陷?它有一些我没有注意到的致命缺点吗?还是可以,只是不经常需要?
只要将对象移出工作线程,这是可能的。以下是您可以做到的方法——请注意,您应该按值保存线程,而不是不使用编译器为您管理内存。
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
异步完成,那么很可能无论如何都不应该使用这样的对象。最有可能的是,您将浪费大部分空闲的线程,因为您不太可能始终保持线程可运行。不可运行的线程本质上是一种浪费的资源。
相关文章:
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 在运行时有条件地删除类成员或跳过调用该成员对象的构造函数
- C++是否有定义的方法来传递指向类的成员对象的成员函数的指针
- (2 问题)"类"类型重新定义(即使 #pragma 一次),以及静态函数内的静态成员对象初始化?
- 声明成员对象而不调用其默认构造函数
- 指向成员对象的指针 - 中断线程
- 是否有更好的方法来封装成员对象可以访问的共享存储池?
- 应该在成员对象上调用析构函数
- 调用成员对象的构造函数
- 将 const 类型引用对象注册为类成员对象C++
- 修改类 c++ 中的成员对象
- 从成员对象调用方法
- 从对象调用成员对象,错误:引用非常量值的初始值必须是左值
- 构造函数,成员对象
- 不能使外部类成为内部类内的成员对象
- 使用从另一个类继承的类的对象初始化成员对象
- 如何避免需要在初始化列表中初始化成员对象
- 初始化具有参数的类成员对象的正确方法
- 将指针添加到成员对象中的指针动态阵列
- C 将成员对象函数分配给类成员功能