#c #multithreading #qt #qt5 #qthread
Вопрос:
Имея в виду Qthread, я попробовал следующее, но, похоже, все по-прежнему работает в том же потоке.
main.cpp
#include "widget.h"
#include <QApplication>
#include "core.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qDebug() << Q_FUNC_INFO << QThread::currentThreadId();
Core core;
Widget w(core);
w.show();
return a.exec();
}
функция.h
#ifndef FUNC_H
#define FUNC_H
#include <QDebug>
#include <QThread>
class Func : public QObject
{
Q_OBJECT
public:
explicit Func()
{
qDebug() << Q_FUNC_INFO << QThread::currentThreadId();
}
void compute()
{
qDebug() << Q_FUNC_INFO << QThread::currentThreadId();
}
};
#endif // FUNC_H
ядро.h
#ifndef CORE_H
#define CORE_H
#include <QObject>
#include "func.h"
class Core : public QObject
{
Q_OBJECT
QThread thread;
Func* func = nullptr;
public:
explicit Core(QObject *parent = nullptr)
{
func = new Func();
func->moveToThread(amp;thread);
connect(amp;thread, amp;QThread::finished, func, amp;QObject::deleteLater);
thread.start();
}
~Core() {
thread.quit();
thread.wait();
}
public slots:
void compute(){func->compute();}
signals:
};
#endif // CORE_H
виджет.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "core.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(Coreamp; core)
{
qDebug() << Q_FUNC_INFO << QThread::currentThreadId();
core.compute(); // This should run on a different thread ?
}
};
#endif // WIDGET_H
Запустив, я получаю результат:
int main(int, char **) 0x107567e00
Func::Func() 0x107567e00
Widget::Widget(Core amp;) 0x107567e00
void Func::compute() 0x107567e00
Выше вывод был из macOS, но в Windows я получил аналогичный результат.
Так что же я делаю не так?
Ответ №1:
Вы не можете вызвать слот compute()
напрямую, он вызовет его в том же потоке, в котором выполняется вызвавший его код (как вы можете видеть на выходе).
Вам нужно запустить слот с помощью механизма сигналов/слотов (или с invokeMethod()
помощью , но давайте проигнорируем это).
Обычно это делается путем подключения started()
сигнала потока к слоту, а затем вызова QThread::start()
из основного потока. Это приведет к тому, что слот будет вызван во вторичном потоке сразу после запуска потока.
Комментарии:
1. Понял! И было бы интересно получить предупреждение, когда вызовы методов для этого объекта не выполняются косвенно. Есть какие-нибудь предложения по этому аспекту? В идеале я хотел бы гарантировать, что вызовы методов этого объекта выполняются в другом потоке (только).