[Interest] QThreads: There's no one way to "do it right"! :)

Bo Thorsen bo at fioniasoftware.dk
Wed Jan 23 17:39:29 CET 2013


Den 23-01-2013 15:07, André Somers skrev:
> Op 23-1-2013 13:08, Bo Thorsen schreef:
>> Den 23-01-2013 08:42, Mandeep Sandhu skrev:
>>> First I thought "I was doing it right"
>>>
>>> Then they said "you're doing it wrong"
>>> (http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/)
>>>
>>> Then I thought "I _finally_ got it right"!!
>>>
>>> Now they say "You were not doing so wrong"
>>> (http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html)!! :D
>>>
>>> End of my Cute poem! :P
>>>
>>> Jokes apart, which method do most ppl here prefer when doing threading?
>> Your question is wrong. Here's why:
>>
>> I have three ways to use QThread (QtConcurrent not included):
>>
>> 1) Worker thread that uses moveToThread approach
>> 2) Subclass QThread do stuff in run() - no event loop involved
>> 3) Subclass QThread and initialize a bunch of objects in run() followed
>> by a call to exec()
>>
>> I'll use any one of them based on what I want to achieve. The third is
>> the one that can get the YOU ARE DOING IT WRONG bunch upset. The
>> argument against it is that it's probably the most difficult to get
>> right, unless you know what you are doing.
> Still, I think it is a valid approach indeed, and might need to be
> mentioned in the docs as well.
>> There are problems in each approach to using QThread, though. And if a
>> developer doesn't understand the issues involved, he will probably end
>> up doing something evil - like moveToThread(this).
> Qt should probably warn when a user does that... I can't think of a
> valid scenario where that would be needed, at least.

No, but I have seen this in several places. As a Qt consultant I see a 
lot of customer code, and this is one of those patterns that raise the 
big warning flags.

>> The reason that #1 is the most popular is that it's the one where
>> developers are less likely to shoot themselves in the foot. Which is
>> true.
> And that's an important argument for documenting QThread the way it has
> been done now. Note that untill Qt 5, the docs basically only showed the
> subclassing (#2) approach. That really has led to issues by users that
> would have been easily avoided by leading them past the 'saver' route #1
> more strongly from the docs to begin with.

I completely agree. It's certainly the approach new QThread users should 
start out with.

>> However, if you're on a project with me, there's no way you are
>> allowed to use anything as big and powerful as QThread, if you don't
>> understand the issues involved with the choices. As the Oracle so
>> perfectly states it: "You can never see past the choices you don't
>> understand." So it's a somewhat moot point, because I believe strongly
>> that anyone using QThread needs to fully understand how objects live in
>> the threads and how signals are propagated to slots between objects when
>> threads are involved. And when you really understand this, all choices
>> are available to you.
> Nice in theory, but not possible to uphold in practice, if you ask me.
> Unless you only work with senior developers, perhaps. Anyway, how do you
> expect your developers to learn about all this if you don't give them
> the chance to shoot themselves in the foot? I am a strong believer that
> getting proficient is about doing and learning from and with your peers.

There are always (well, I hope so) senior coders on a project. They can 
handle the dangerous parts, which is the code around the use of QThread 
itself. This is the intersection point between the threads, and it's the 
place where things are most difficult. Inside each of the threads, the 
juniors can proceed to do their parts.

>> So if someone just says he prefers one approach over all the others,
>> it's because he doesn't fully understand the pros and cons for the
>> choices. And that's why your question is wrong. There is no right
>> choice. Which fortunately for you is exactly what you had in the mail
>> subject :) However, if someone answers that he thinks #1 is more often
>> appropriate for the task at hand, then I won't argue against it.
>>
>> I have answered this before on the mailing list, and I probably will again.
>>
>> A final note. I have three rules about threading:
>>
>> 1) Don't do it.
>> 2) Don't do it.
>> 3) Don't do it yet.
> What a silly list of rules.

Yes :) It is, of course, said with a big tongue-in-cheek.

>   A circular saw is also a dangerous tool, but
> that does not mean you should not use them. It only means that this is
> tool that needs to be yielded more responsively than some other tools.
> Just like there is a place for each of the three ways you mentioned you
> can use QThread, there is a place for using threading in your project as
> well. And I think it is a tool you, as a programmer, better familiarize
> yourself with if you want to be able to write software that will perform
> on todays multi-core systems, no matter how difficult a tool it is to
> yield well.

There is a serious side to the three ridiculous rules, though. It's so 
often I hear coders think something like "we can just do this in a 
thread", and the point of the rules is to make them stop right there and 
reconsider. If you have a single thread application there is no "just" 
in adding threads. (Unless it's QtConcurrent, which is almost safe.) 
Everything gets a lot more complicated and maintenance and bugfixing 
becomes non-trivial.

In Qt there are even more things available to us. The event based coding 
takes away a big chunk of what some coders would think has to be done in 
threads. We can also chop up big workloads in pieces and have the event 
loop start each of them in turn. And so on.

If threads are the right solution for a problem, then go ahead and use 
them. But I will do a lot to avoid them before caving in.

>> If someone on this list is considering threads in their projects, he
>> should educate himself to the point where he understands the choices and
>> why those three rules makes sense. Then and only then, can he consider
>> himself allowed to wield the big hammer :)
> Educating oneself is tightly connected to trying your hand at it. Just
> learning from books or documentation pages isn't going to be enough. And
> no, you don't do that for the first time on an important project for a
> customer.

Yes, but there are so many other things a developer can do than touch 
the most difficult parts of the code. And there are many things to learn 
before using QThreads properly - like how QObjects work, what the 
parent-child relationship is, how signals are sent, how they differ from 
events, etc. If someone doesn't know this, he can't appreciate the 
trouble he can get into with QThread.

Of course, if it's a one person shop or the team are all new to Qt, and 
threads are necessary. Then yes, someone has to do this. Which should be 
a good thing for me, as they are going to call a Qt expert to come and 
help them soon :) (That was with a tongue-in-cheek too.)

> Also, it is easy to say that someone should "educate themselves", but
> that is not a statement suitable for the documentation pages, is it? I
> actually find it somewhat gratuit. Either point people towards the
> sources where they might gain the insights you think people need in
> order to use threads safely, or don't bother to comment this way at all.

Sure, I wasn't thinking about the Qt documentation when I wrote this, as 
I was just replying to Mandeeps question. I agree that it would be out 
of place to attempt writing about the concepts someone should understand 
before using the classes.

Bo Thorsen.

-- 
Fionia Software - Qt experts for hire.




More information about the Interest mailing list