PDA

View Full Version : Launching QThreads from a loop



lynchkp
9th September 2012, 00:31
Hello,

I have an algorithm which runs on image data, which I have implemented so that it occurs on a separate QThread to prevent locking the GUI. This works perfectly when I am running it with one image. Instead, I'd like to run a loop over multiple images, but only one thread executing at a time... something along the lines of...


// Loop over all files.
int i = 0;
while (i < selected_files.size()) {

QThread* thread = new QThread;
Worker *worker = new Worker(filenames,s2);
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
thread->start();

i+=step;
}


But it currently runs all the threads at the same time. I want this to operate one thread at a time. I know this is probably very basic, but I am still learning threaded programming!

Thanks!

ChrisW67
9th September 2012, 04:18
Then only start one thread that processes a queue of files rather than one thread for each entry in the queue.

amleto
9th September 2012, 11:27
someclass::slot_make_next_thread()
{
// need some saved variables so we know which 'filenames' and which 's2' to pass on.
make_thread(filenames, s2);
}

someclass::make_thread(filenames, s2)
{
QThread* thread = new QThread;
Worker *worker = new Worker(filenames,s2);
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(thread, SIGNAL(finished()), this, SLOT(slot_make_next_thread()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
thread->start();
}

wysota
9th September 2012, 11:37
Another solution:


QImage algorithm(QImage img) {
// ...
}

QList<QImage> imagesToProcess = ...;
QThreadPool::globalInstance()->setMaxThreadCount(1); // if you want to force to have only one thread at a time
QFuture<QImage> future = QtConcurrent::mapped(imagesToProcess, algorithm);
QFutureWatcher<QImage> *watcher = new QFutureWatcher<QImage>(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), ..., ...);