QT5 Межпотоковая связь, слот не вызывается в контексте "this"
У меня есть объект MainWorker, запущенный как отдельный поток, благодаря методу moveToThread. MainWorker имеет член SubWorker, который также запускается как отдельный поток. Оба потока работают в бесконечных циклах.
Идея заключается в том, что MainWorker и SubWorker выполняют несколько отдельных вычислений. Всякий раз, когда SubWorker завершает вычисления, он должен уведомить MainWorker о результате.
Поэтому я интуитивно установил первое соединение между сигналом, излучаемым SubWorker, и слотом MainWorker, но он не работал, поэтому я сделал еще два соединения, чтобы исключить некоторые потенциальные проблемы:
connect(subWorker, &SubWorker::stuffDid, this, &MainWorker::reportStuff)); //1
connect(subWorker, &SubWorker::stuffDid, subWorker, &SubWorker::reportStuff); //2
connect(this, &MainWorker::stuffDid, this, &MainWorker::reportStuffSelf); //3
Кажется, что то, что не работает, это именно то, что мне нужно - кросс-потоковая связь, потому что соединения 2 и 3 работают как положено. У меня вопрос: как мне заставить работать соединение 1?
Редактировать: Очевидно, после объяснения Карстена, становится ясно, что бесконечный цикл блокирует цикл EventLoop. Итак, новый вопрос, как я могу отправлять сообщения (сигналы, что угодно) из потока бесконечного цикла в его родительский поток?
Я новичок в Qt, есть большая вероятность, что я все понял неправильно. Вот минимальный (не) рабочий пример:
MainWorker.h
class MainWorker : public QObject
{
Q_OBJECT
public:
MainWorker() : run(false) {}
void doStuff()
{
subWorker = new SubWorker;
subWorkerThread = new QThread;
subWorker->moveToThread(subWorkerThread);
connect(subWorkerThread, &QThread::started, subWorker, &SubWorker::doStuff);
if(!connect(subWorker, &SubWorker::stuffDid, this, &MainWorker::reportStuff)) qDebug() << "connect failed";
connect(subWorker, &SubWorker::stuffDid, subWorker, &SubWorker::reportStuff);
connect(this, &MainWorker::stuffDid, this, &MainWorker::reportStuffSelf);
subWorkerThread->start();
run = true;
while(run)
{
QThread::currentThread()->msleep(200);
emit stuffDid();
}
}
private:
bool run;
QThread* subWorkerThread;
SubWorker* subWorker;
signals:
void stuffDid();
public slots:
void reportStuff()
{
qDebug() << "MainWorker: SubWorker did stuff";
}
void reportStuffSelf()
{
qDebug() << "MainWorker: MainWorker did stuff (EventLoop is not blocked)";
}
};
SubWorker.h
class SubWorker : public QObject
{
Q_OBJECT
public:
SubWorker() : run(false) {}
void doStuff()
{
run = true;
while(run)
{
qDebug() << "SubWorker: Doing stuff...";
QThread::currentThread()->msleep(1000);
emit stuffDid();
}
}
private:
bool run;
public slots:
void reportStuff()
{
qDebug() << "SubWorker: SubWorker did stuff";
}
signals:
void stuffDid();
};
main.cpp
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MainWorker *mainWorker = new MainWorker;
QThread *mainWorkerThread = new QThread;
mainWorker->moveToThread(mainWorkerThread);
QObject::connect(mainWorkerThread, &QThread::started, mainWorker, &MainWorker::doStuff);
mainWorkerThread->start();
return a.exec();
}