简单的多线程与Qt:我这样做是正确的
Simple multithreading with Qt: am I doing this right?
我是新来的StackOverflow,想知道我这样做是否正确:
我正在写一个简单的Qt应用程序来测试多线程(我也是全新的东西)。我创建了一个包含小部件的主窗口和一个类MyThread,它继承了QThread并覆盖了run()方法。
应用程序简单地显示两个按钮,"开始计数器"answers"停止计数器",和一个文本字段。当"启动计数器"被按下时,一个工作线程被创建并在后台运行,在while循环中不断增加计数器,并用更新的值向主线程(GUI所在的地方)发出信号。当"停止计数器"被按下时,一个信号被发送到主线程停止while循环,计数器停止直到"开始计数器"被再次按下。
这工作得很好…但这是最好的方法吗?我是新手,读过很多人说"不要子类化QThread",其他人说"子类化QThread",这有点令人困惑。如果这不是实现这类事情的最佳方式(在带有"开始"answers"停止"按钮的后台线程中运行计算密集型循环),那是什么?如果我做错了,我怎么才能做对呢?我不想用错误的方法学习。
谢谢!下面是代码:
MyThread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QMutex>
class MyThread : public QThread
{
Q_OBJECT
public slots:
void stopRunning();
protected:
virtual void run();
signals:
void signalValueUpdated(QString);
private:
bool isRunning;
};
MyThread.cpp
#include "MyThread.h"
#include <QString>
void MyThread::run()
{
qDebug("Thread id inside run %d",(int)QThread::currentThreadId());
static int value=0; //If this is not static, then it is reset to 0 every time this function is called.
isRunning = 1;
while(isRunning == 1)
{
QString string = QString("value: %1").arg(value++);
sleep(1/1000); //If this isn't here, the counter increments way too fast and dies, or something; the app freezes, anyway.
emit signalValueUpdated(string);
}
}
void MyThread::stopRunning()
{
isRunning = 0;
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QApplication>
#include <QPushButton>
#include <QHBoxLayout>
#include <QLineEdit>
#include "MyThread.h"
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
private:
//Widgets
QHBoxLayout * boxLayout;
QPushButton * startButton;
QPushButton * stopButton;
QLineEdit * lineEdit;
MyThread thread;
};
#endif
MainWindow.cpp
#include "MainWindow.h"
MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
{
boxLayout = new QHBoxLayout(this);
startButton = new QPushButton("Start Counter", this);
stopButton = new QPushButton("Stop Counter", this);
lineEdit = new QLineEdit(this);
boxLayout->addWidget(startButton);
boxLayout->addWidget(stopButton);
boxLayout->addWidget(lineEdit);
qDebug("Thread id %d",(int)QThread::currentThreadId());
//When the start button is pressed, invoke the start() method in the counter thread
QObject::connect(startButton,SIGNAL(clicked()),&thread,SLOT(start()), Qt::QueuedConnection);
//When the stop button is pressed, invoke the stop() method in the counter thread
QObject::connect(stopButton,SIGNAL(clicked()),&thread,SLOT(stopRunning()), Qt::QueuedConnection);
//When the counter thread emits a signal saying its value has been updated, reflect that change in the lineEdit field.
QObject::connect(&thread,SIGNAL(signalValueUpdated(const QString&)),lineEdit,SLOT(setText(const QString&)), Qt::QueuedConnection);
}
大多数时候QThread子类化是在Qt中做线程的错误方式,我建议你阅读一篇关于线程,事件循环和其他可以给你一个如何在Qt中更好地使用线程的想法的文章。但是不要听那些认为只有一种正确的方法来使用QThread的人。有两种方法,虽然一般不需要子类化,但有时可能有用。你只需要使用非子类化的方式,直到你真的需要子类化。在您的特殊情况下,您不需要子类化。
将sleep(1/1000);
替换为msleep(100);
,一切都会好的
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 为什么一个向量上的多线程操作很慢
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 全局变量 多读取器 一个写入器多线程安全?
- boost::文件系统::recursive_directory_iterator多线程安全
- 如何阻止TensorFlow的多线程
- 如何在多线程中正确使用unique_ptr进行多态性?
- 并发/多线程:是否可以以这种方式生成相同的输出?
- sigwait() 在多线程程序中不起作用
- 多线程程序中出现意外的内存泄漏
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 多线程时,您该怎么做才能停止堆栈空间
- 多线程应用程序,我做得对吗
- 当gemm做时,sgemm不多线程
- 是否有任何方法允许多线程程序与这样的循环
- 简单的多线程与Qt:我这样做是正确的