QThread 对象作为 worker class 的成员
QThread object as a member of worker class
我读过很多文章,关于为什么 subclassing QThread
在大多数情况下是个坏主意,以及如何正确使用 QThread
,调用 moveToThread
方法。 Here我们可以看到这种设计的典型例子。
我正在设计的class需要满足以下要求:
它想使用信号和槽,所以我将需要一个事件循环并且将使用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 的(私有)成员,但我从未在任何示例或其他人的代码中看到过。
所以我想知道这个设计是不是有缺陷?它是否有一些我没有注意到的致命缺点?或者还可以,只是不经常需要?
只要您将对象移出工作线程,这是可能的。以下是您可能会这样做的方法 - 请注意,您应该按值保留线程,没有必要不使用编译器为您管理内存。
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
异步完成,您很可能无论如何都不应该使用这样的对象。最有可能的是,您将浪费大部分空闲的线程,因为您不太可能始终保持线程可运行。不可运行的线程本质上是一种浪费的资源。
我读过很多文章,关于为什么 subclassing QThread
在大多数情况下是个坏主意,以及如何正确使用 QThread
,调用 moveToThread
方法。 Here我们可以看到这种设计的典型例子。
我正在设计的class需要满足以下要求:
它想使用信号和槽,所以我将需要一个事件循环并且将使用
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 的(私有)成员,但我从未在任何示例或其他人的代码中看到过。
所以我想知道这个设计是不是有缺陷?它是否有一些我没有注意到的致命缺点?或者还可以,只是不经常需要?
只要您将对象移出工作线程,这是可能的。以下是您可能会这样做的方法 - 请注意,您应该按值保留线程,没有必要不使用编译器为您管理内存。
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
异步完成,您很可能无论如何都不应该使用这样的对象。最有可能的是,您将浪费大部分空闲的线程,因为您不太可能始终保持线程可运行。不可运行的线程本质上是一种浪费的资源。