如何在不同步的情况下使用 QThreads

how to use QThreads without sync

我有 3 个 classes,A、B 和 C;

这是class答: A.h

#ifndef A_H
#define A_H

#include <QObject>

class A : public QObject {

    Q_OBJECT

public:

    A();

    void doWork();

signals:

    void ready(QString str, QVector<double> v);
};

#endif // A_H

A.cpp

#include "A.h"

#include <QVector>

A::A() {

}

void A::doWork() {

    QVector<double> x;
    for(int i = 0 ; i < 10; i++) {
        x.push_back(i);
    }

    emit ready("A ready", x);
}

B和C完全一样。只有 class B 中 doWork 中的循环直到 10000,而 C 中直到 100000000(8 个零)。

为了测试使用 QThreads 我创建了 3 个 QLabel:

QLabel* lbl_a;
QLabel* lbl_b;
QLabel* lbl_c;

这是我的主窗口代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QThread>
#include "A.h"
#include "B.h"
#include "C.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);

    ~MainWindow();

public slots:

    void handlerA(QString str, QVector<double> v);
    void handlerB(QString str, QVector<double> v);
    void handlerC(QString str, QVector<double> v);


private slots:
    void on_btn_start_clicked();

private:
    Ui::MainWindow *ui;

    A* a;
    B* b;
    C* c;
    QThread thread_a;
    QThread thread_b;
    QThread thread_c;
};

#endif // MAINWINDOW_H

MainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow) {

    ui->setupUi(this);

    a = new A();
    b = new B();
    c = new C();

    a->moveToThread(&thread_a);
    b->moveToThread(&thread_b);
    c->moveToThread(&thread_c);

    connect(a, SIGNAL(ready(QString, QVector<double>)), this, SLOT(handlerA(QString, QVector<double>)));
    connect(b, SIGNAL(ready(QString, QVector<double>)), this, SLOT(handlerB(QString, QVector<double>)));
    connect(c, SIGNAL(ready(QString, QVector<double>)), this, SLOT(handlerC(QString, QVector<double>)));

    thread_a.start();
    thread_b.start();
    thread_c.start();
}

MainWindow::~MainWindow() {


    thread_a.wait();
    thread_b.wait();
    thread_c.wait();
    delete ui;
}

void MainWindow::handlerA(QString str, QVector<double> v) {

    QVector<double> x = v;
    ui->lbl_a->setText(str);
}

void MainWindow::handlerB(QString str, QVector<double> v) {

    QVector<double> x = v;
    ui->lbl_b->setText(str);
}

void MainWindow::handlerC(QString str, QVector<double> v) {

    QVector<double> x = v;
    ui->lbl_c->setText(str);
}

void MainWindow::on_btn_start_clicked() {

    a->doWork();
    b->doWrok();
    c->doWork();
}

我预计 lbl_a 会先出现然后 lbl_b 然后 lbl_c 但无论我如何更改 for 循环,它们总是一起出现。

有什么问题?

您没有在每个线程中执行 for 循环。您正在同一个线程中执行它们,即 main 线程。

这是因为您直接从插槽 on_btn_start_clicked 调用函数 doWork,作为普通函数运行。

您应该完全删除对 doWork 的调用。 相反,将信号 QThread::started() 连接到您的 doWork 函数。有了这个,一旦线程启动,它将从新线程发出这个信号,从线程执行你的 doWork 函数。

connect(&thread_a, &QThread::started, a, &A::doWork);

当然,abc必须是QObjects,函数doWork必须是槽


注意:从 Qt 5.10 和 C++17 开始,您还可以使用静态函数 QThread::create,它会创建一个线程,并在启动时执行传递的函数。