Qthread 调用只运行一次
Posted
技术标签:
【中文标题】Qthread 调用只运行一次【英文标题】:Qthread calls run only once 【发布时间】:2015-05-22 13:44:31 【问题描述】:您好,我正在尝试在 Qt 的控制台应用程序中创建线程。
我的主要方法是:
#include<featurematcher.h>
#include<QCoreApplication>
int main(int argc, char *argv[])
QCoreApplication a(argc, argv);
FeatureMatcher * fm = new FeatureMatcher();
fm->start();
return a.exec();
我的 FeatureMatches 类如下:
#ifndef FEATUREMATCHER_H
#define FEATUREMATCHER_H
#include<QThread>
class FeatureMatcher:public QThread
Q_OBJECT
public:
FeatureMatcher();
void run();
;
#endif // FEATUREMATCHER_H
和cpp文件:
#include "featurematcher.h"
#include <iostream>
FeatureMatcher::FeatureMatcher()
void FeatureMatcher::run()
std::cout<<"Process"<<std::endl;
我的问题是,当我开始运行程序时,它只调用一次运行方法。我期望输出是无限数量的“进程”打印出来,但它只打印一次。 我在哪里失踪?
【问题讨论】:
你想用QThread解决什么问题?如果你希望 run 被重复调用,你可能根本不需要线程,而是一个 QTimer。 一个线程只能运行一次run
。如果你想多次执行一个任务,你需要一个循环。
@Alexander 谢谢。我在 GUI 上使用线程。在那,它自己调用运行,但后来我知道这是因为 GUI 正在重新绘制自己并一次又一次地调用线程。
【参考方案1】:
首先一般是not a good idea to inherit QThread
。但是,如果您绝对必须这样做,则必须自己实现循环。您可以通过两种方式做到这一点。
你可以创建一个QTimer
,然后运行QThread::exec
:
void FeatureMatcher::run()
this->moveToThread(this);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), SLOT(onTimer()));
timer->setInterval(1000);
timer->start();
exec();
或者你可以创建一个无限循环:
void FeatureMatcher::run()
while (1)
std::cout<<"Process"<<std::endl;
更新了第一个示例 #2。
【讨论】:
您的第一个示例不正确。onTimer
插槽不会在 FeatureMatcher
线程上下文中执行。
@hank:谢谢,好久没用了。更新示例。
我正要尝试在运行中使用while循环。但是我在不需要使用任何循环的 gui 应用程序中使用了线程。一旦我启动了线程,它的 run 函数每次都会自行调用。控制台和 gui 应用程序上的线程有什么不同吗?
@Amartel:这也是不正确的。计时器已经在FeatureMatcher
线程上下文中创建,因此不需要timer->moveToThread(this)
。这里的问题是FeatureMatcher
对象本身是在主线程中创建的,它的onTimer
也将在主线程上下文中执行。要“修复”这个问题,您应该在 FeatureMatcher
构造函数中使用 hack:this->moveToThread(this)
,但这被认为是一种非常糟糕的做法。
@Muhammet Ali Asan:没有区别。 Once I started the thread its run function is called every time by itself
- 这听起来很奇怪。 @hank:再次感谢。已编辑。【参考方案2】:
虽然我同意 Amartel 上面所说的(“继承 QThread 不是一个好主意”)。它仍然是一种选择。
如果你仍然想继承 QThread(你真的,可能不需要)试试这个:
#ifndef FEATUREMATCHER_H
#define FEATUREMATCHER_H
#include<QThread>
class FeatureMatcher:public QThread
Q_OBJECT
public:
FeatureMatcher();
void loopRun();
private:
void run();
;
#endif // FEATUREMATCHER_H
然后将 looprun() 函数添加到您的 .cpp 文件中:
#include "featurematcher.h"
#include <iostream>
FeatureMatcher::FeatureMatcher()
void FeatureMatcher::run()
std::cout<<"Process"<<std::endl;
void FeatureMatcher::looprun()
while(1)
start();
希望我能帮到你。在极少数情况下继承 QThread 是有益的。
这是与/帮助开发 QThread 模块的人之一的博客文章,其中解释了一些困惑:https://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/
但是,这篇文章提出了一些反对始终使用工作线程而不是继承 QThreads 的论点:http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html
【讨论】:
run 是受保护的虚拟程序,当您执行 QThread::start() 时会调用它。你不应该直接调用 run 。你的实现根本不是一个线程。 修复了这个问题。感谢您指出科雷亚!自从我做这种 QThread 实现以来已经有一段时间了。以上是关于Qthread 调用只运行一次的主要内容,如果未能解决你的问题,请参考以下文章
QThread多线程编程经典案例分析(三种方法,解释了为什么使用moveToThread的根本原因,即为了避免调用QThread::exec() )