我应该在线程上调用 processEvents() 吗?
Should I call processEvents() on a thread?
QThread
文档提出了两种使代码在单独的线程中运行的方法。如果我使用moveToThread
方法,我必须调用processEvents()
来发出超时,以执行 lambda。这似乎花费了很多 CPU。为什么会这样?
class Worker : public QObject
{
Q_OBJECT
QTimer* timer;
bool m_abort = false;
public:
Worker() {}
void abort() {m_abort = true;}
public slots:
void run() {
timer = new QTimer;
connect(timer, &QTimer::timeout, []{qDebug() << "computed";});
timer->start(1000);
forever {
if (m_abort) break;
QCoreApplication::processEvents();
}
}
};
class MainWidget : public QWidget
{
Q_OBJECT
QThread thread;
Worker* worker;
public:
MainWidget()
{
worker = new Worker;
worker->moveToThread(&thread);
connect(this, &MainWidget::start, worker, &Worker::run);
thread.start();
emit start();
}
~MainWidget(){worker->abort(); thread.quit(); thread.wait();}
signals:
void start();
};
但是,如果我子类QThread并重新实现run((,则没有必要调用processEvents。而且 CPU 成本似乎更低。为什么?
class Worker : public QThread
{
public:
Worker() {}
protected:
void run() override {
QTimer timer;
connect(&timer, &QTimer::timeout, []{qDebug() << "computed";});
timer.start(1000);
exec();
}
};
class MainWidget : public QWidget
{
Q_OBJECT
Worker* worker;
public:
MainWidget()
{
worker = new Worker;
worker->start();
}
};
你的run((函数"阻塞"线程。它在线程上下文中被调用,但从不返回。这意味着,一旦调用 run(( 函数,线程中的事件循环就不再执行。
要使计时器事件调用您的 lambda,必须处理事件循环。 如果要像这样修改运行函数:
void run() {
timer = new QTimer(this);
connect(timer, &QTimer::timeout, []{qDebug() << "computed";});
timer->start(1000);
// don't loop here, instead exit the function
// and let the thread return back to the event loop
}
那么你的 lambda 应该被调用。线程也将继续运行,直到您调用thread.quit()
注意:您也可以直接连接到线程的"已启动"信号:
connect(&thread, &QThread::started, worker, &Worker::run);
thread.start();
moveToThread 方法可以通过在线程发出开始后立即调用 run(( 函数来改进。
但我仍然不知道为什么我最初表达的方式不起作用。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 构造函数正在调用一个使用当前类类型的函数
- 变量没有改变?通过向量的函数调用
- 没有为自己的结构调用列表推回方法
- 调用'begin(int [n])'没有匹配函数
- 什么时候调用析构函数
- 如何用参数值调用函数(仅在运行时已知)
- 我应该在线程上调用 processEvents() 吗?
- QCoreApplication::processEvents-为什么必须仅从主线程调用它