여러 스레드가 특정 시점에 시작되도록 보장하는 Qt 용 장벽 유사 동기화 프리미티브를 작성하려고합니다. 그러나 나는 신호 (예 : started())가 작동하지 않는 상황에 처해있는 것처럼 보입니다.여러 스레드가 시작될 때까지 대기 중 (시작되지 않음)
최소한의 (비) 작동 예제를 컴파일하기 위해 코드를 축소하려고했습니다.
========
main.cpp
========
#include <QtCore>
#include <QCoreApplication>
#include "qmultithreadwaiter.hpp"
#include <QSignalMapper>
#include <qdebug.h>
#define dlog qDebug()
class Test: public QThread {
public:
virtual void run() {
QThread::sleep(500);
}
};
int main(int argc, char *argv[ ]) {
QCoreApplication a(argc, argv);
Test t1, t2;
QMultiThreadWaiter w;
w.addThread(1, &t1);
w.addThread(2, &t2);
t1.start();
t2.start();
w.wait4all();
dlog << "Wait completed";
return 0;
}
=========================
qmultithreadwaiter.hpp
=========================
// Qt includes
#include <QSignalMapper>
#include <QMap>
#include <QThread>
class QMultiThreadWaiter: public QThread {
Q_OBJECT
QMap < int, bool > started;
QSignalMapper sm;
private slots:
void threadStarted(int id);
void someThreadStarted();
signals:
void allStarted();
public:
QMultiThreadWaiter();
void addThread(int id, QThread* t);
void wait4all();
};
=================
qmultithreadwaiter.cpp
=================
#include "qmultithreadwaiter.hpp"
// Qt includes
#include <QThread>
// Debug includes
#include <qdebug.h>
#define dlog qDebug()
// Project includes
void QMultiThreadWaiter::threadStarted(int id) {
dlog << "Thread #" << id << " started!";
started[ id ] = true;
QMapIterator < int, bool > mi(started);
while (mi.hasNext()) {
mi.next();
if (!mi.value())
return;
}
dlog << "All threads started!";
// All threads are started
emit allStarted();
}
void QMultiThreadWaiter::addThread(int id, QThread* t) {
dlog << "Adding thread " << t << " with id " << id;
sm.setMapping(t, id);
connect(t, SIGNAL(started()), &sm, SLOT(map()), Qt::QueuedConnection);
connect(t, SIGNAL(started()), this, SLOT(someThreadStarted()),
Qt::QueuedConnection);
}
void QMultiThreadWaiter::wait4all() {
dlog << "Starting this thread";
start();
dlog << "Going to wait";
wait();
dlog << "Wait finished";
}
QMultiThreadWaiter::QMultiThreadWaiter() {
sm.moveToThread(this);
connect(&sm, SIGNAL(mapped(int)), this, SLOT(threadStarted(int)),
Qt::QueuedConnection);
connect(this, SIGNAL(allStarted()), this, SLOT(quit()),
Qt::QueuedConnection);
connect(this, SIGNAL(started()), this, SLOT(someThreadStarted()),
Qt::QueuedConnection);
}
void QMultiThreadWaiter::someThreadStarted() {
dlog << "Some thread started!";
}
출력 :
Adding thread QThread(0x28fefc) with id 1
Adding thread QThread(0x28fef4) with id 2
Starting this thread
Going to wait
<stuck>
어떤 이상한 것은 심지어 someThreadStarted()
이 this
요구되지 않는다는 점이다. 제발, 조언 해.
내가 'started()'신호는 스레드 내부에서 eventloop을 사용할 때만 emmited라고 생각합니다. 그렇지 않으면 그것을 emmited되지 않습니다. run 메소드에'exec()'를 넣고 신호가 emmited인지 확인하십시오. –