qt4-preview-feedback@trolltech.com
[Top] [All Lists]

possible QtConcurrent issue/problem

Subject: possible QtConcurrent issue/problem
From: Michael Berg
Date: Tue, 19 Feb 2008 15:51:02 +0100
Hi,

The below example shows a problem (or at least an issue one has to be
aware of) with QtConcurrent. The main() is supposed to spawn x threads
which execute b(). Now b() spawns itself one thread to execute a(). After
spawning a thread the current thread always waits for the spawned one to
finish.

The problem is that QtConcurrent uses a QThreadPool whose amount of
handled threads depends on the number of cores. Only this amount of
threads will be executed at a time. Now by default I got 2 cores in my
computer. If I spawn 2 threads for b(), I got 2 threads created and
then main() waits for the first b() to finish. But now every b() spawns
another thread for a(). Thus for 2 b() threads we got 4 threads running,
but unfortunately thread 3 (the one spawned by the first b) will never
run, unless one b() finishes. But no b() can finish until the a()s ran
(thread 3 and 4).

So the only way is to be aware of this behavior and 1.) either to increase
the number of allowed threads or 2.) change the code. In the example at
least 3 threads have to be allowed to run at a time, so one of the b()s
can finish.

Now this example might look contrived, but in my real case I had an object
representing an complex computation which spawned threads via
QtConcurrent to do it's work. Somewhere else in my code I had to run this
computation for 30 times. There I again used QtConcurrent::run() to spawn
30 threads and let Qt handle the concurrency. So the problem is more that
a user of some piece of code shouldn't know how this code has been
implemented. But in my case I have the feeling that I have to know, else I
can't adjust the amount of maximum threads or adjust my code otherways.

What's other peoples opinion on that - am I missing something ? I'm aware
that restricting (by default) the amount of threads to the amount of cores
is a good thing, but the case I described and the rational is valid as
well, I think.

Some related question is:
Occasionally (if I spawn more b()s in the example the probability
increases) I get the following errors when starting the example:

>GThread-ERROR **: GThread system may only be initialized once.
>aborting...

or also

>(process:6581): GThread-ERROR (recursed) **: GThread system may only be
>initialized once.
>aborting...

I'm running Suse10.1 on a 64 bit machine. It doesn't feel good to not know
what causes these errors, if I want to keep using QtConcurrent.

Any help ? Suggestions.

Thanks in advance.



Michael



the code:

#include <QtCore>

using namespace QtConcurrent;

void a(int id){
        qDebug() << "in a - id: " << id;
}

void b(int id){
        QFuture<void> ra = run(&a, id + 100);
        qDebug() << "in b - id: " << id;
        ra.waitForFinished();
}
        
int main (int argc, char **argv){
        QThreadPool::globalInstance()->setMaxThreadCount(3);
        qDebug() << "maxThreadCount: " 
        << QThreadPool::globalInstance()->maxThreadCount()
        << "idealThreadCount: " << QThread::idealThreadCount();
        QFutureSynchronizer<void> fs;
        for(int i = 0; i < 2; i++)
                fs.addFuture(run(&b, i));
        fs.waitForFinished();   
        
        return 0;
}

To unsubscribe - send "unsubscribe" in the subject to 
qt4-preview-feedback-request@xxxxxxxxxxxxx

<Prev in Thread] Current Thread [Next in Thread>