Hi everyone,
I'm using QTimers in a multithread Qt5 application. Here is my structure:
- MainWindow.cpp creates a thread A and its worker object:
worker = new SudokuComputeWorker();
worker->moveToThread(t);
connect(t, SIGNAL(started()), worker, SLOT(doWork()));
connect(worker, SIGNAL(scoresFetched(const QList<double>*)), worker, SLOT(workDone()));
t->start();
t = new QThread();
worker = new SudokuComputeWorker();
worker->moveToThread(t);
connect(t, SIGNAL(started()), worker, SLOT(doWork()));
connect(worker, SIGNAL(scoresFetched(const QList<double>*)), worker, SLOT(workDone()));
t->start();
To copy to clipboard, switch view to plain text mode
- Thread A creates N threads B1, B2,... BN, each with its own worker object:
foreach (SearchComponent* s, algos) {
SudokuWorker* w;
w = new SudokuWorker(i, s, _myBLOCKS_SIZE, _myON_DISTRIBUTION, _myHOW_MANY_PROBLEMS);
w->moveToThread(t);
connect(t, SIGNAL(started()), w, SLOT(doWork()));
connect(w, SIGNAL(scoreFetched(int)), w, SLOT(workDone()));
t->start();
}
foreach (SearchComponent* s, algos) {
QThread* t = new QThread();
SudokuWorker* w;
w = new SudokuWorker(i, s, _myBLOCKS_SIZE, _myON_DISTRIBUTION, _myHOW_MANY_PROBLEMS);
w->moveToThread(t);
connect(t, SIGNAL(started()), w, SLOT(doWork()));
connect(w, SIGNAL(scoreFetched(int)), w, SLOT(workDone()));
t->start();
}
To copy to clipboard, switch view to plain text mode
- Whats happens in SudokuWorker::doWork()?
void SudokuWorker::doWork()
{
my_AlgoToTest->attachTimer(t);
for (; _myNbTimesToRun > 0 && !_myInterruptNow; _myNbTimesToRun--) {
qDebug() << *my_AlgoToTest << _myNbTimesToRun;
SudokuState s(my_BlockSize);
my_AlgoToTest->resetAlgorithm();
my_AlgoToTest->runAlgorithm(&s);
scores.append(my_AlgoToTest->getBestReward());
testsCompleted++;
}
delete t;
emit scoreFetched(my_AlgoIndex);
}
void SudokuWorker::doWork()
{
QTimer* t = new QTimer(NULL);
my_AlgoToTest->attachTimer(t);
for (; _myNbTimesToRun > 0 && !_myInterruptNow; _myNbTimesToRun--) {
qDebug() << *my_AlgoToTest << _myNbTimesToRun;
SudokuState s(my_BlockSize);
my_AlgoToTest->resetAlgorithm();
my_AlgoToTest->runAlgorithm(&s);
scores.append(my_AlgoToTest->getBestReward());
testsCompleted++;
}
delete t;
emit scoreFetched(my_AlgoIndex);
}
To copy to clipboard, switch view to plain text mode
[Notice: Normal if the sense of the code doesn't seem obvious, I just let the things in relation with the threads and the worker. Threads and objects deletion is properly set.]
Note that in attachTimer(), the timer is set as "single shot: true". Moreover, in runAlgorithm(), there is the "timer->start(1000)" statement.
Now the problem:
The timers aren't started, as if the threads in which the workers are had no event loops. Indeed, when I want to show the remaining time of the timers juste after they have started, I have random numbers (all but 1000) that shows up. This is the mark of an uninitialized value, and it occurs because somehow the timers don't find their event loop.
Have you any idea of what I'm doing wrong? I thought I applied as I had to the method presented in "You're doing it wrong"...
Thank you!!
Bookmarks