PDA

View Full Version : NESTED threads. one thread inside another



huba
8th July 2010, 00:25
Hi everyone!

My question is: Is it possible to create nested threads in Qt4?

This is what I exaclly mean:
making an object (lets call it outerObject) that inherits from QThread and has - as one of its members - some other object of other class that also inherits from QThread (lets call it innerObject). Than calling

innerObject.moveToThread(&outerObject)
to make it live in the thread reprezented by outerObject. Then I start outerObject's thread by calling

outerObject.start();
and also start the thread reprezented by innerObject in similar way. Both of my threads has it's event loops running and there are signals and slots betwen them.

I was trying to find the answer to this question on google and Qt's documentation, but haven't succeeded.
I'm asking this question because I implemented what I described and it generally works (I use currentThreadId(); to watch how it works) but the program breakes down randomly on run. Debugging gives only reference to some Asembler code, so I started to think taht maybe Qt dosen't allowe for one thread inside another.

If any of you have any idea, I'll be very gratfull for sharing your knowladge with me, as orginazing my progrem in that way would make it much easier to implement, that without nested threads.

Thanks in advance!!

borisbn
8th July 2010, 05:04
This is quite normal thing to make nested threads (I did this, and my program worked fine). Maybe your crashes are because of not synchronized read/write of gui objects, or you do not wait for thread to stop at it's end or other bug, do not linked with nested thread. Try to write simple program with one thread inside other and do nothing in them

huba
8th July 2010, 14:05
Thanks for your reply borisbon!
Its valuble to me as it tells me that I should look fot the bug in my program somewere else.

wysota
8th July 2010, 15:57
Please remember that the thread object (subclass of QThread) doesn't have anything to do with the actual thread it represents. When talking about Qt objects thread affinity only dictates which thread handles events for the QThread object and its children, the thread represented by the QThread object is not affected in any way. Threads by definition are independent so they can't actually be "nested", you are nesting thread controller objects instead.

huba
21st July 2010, 00:40
Just to let you all know, I found the bug in my program. It had nothing to do with nested threads:) So I can confirm it by my own experiance that it works:)

thanks wysota for your answer. I'm actually familiar with what you're saying that thread object (subclass of QThread) doesn't have anything to do with the actual thread it represents. However I don't certainly agree with what you say later, that threads are not "nested". I dont wanna argue as I am a beginner, but it seems for me that in SOME way threads are nested - in the way how processor time is shared between them. Lets say I start one thread1, then start thread2 inside thread1 and then thread3 inside thread2. As I understand this, the processor gives 1/2 of the time it has for thread1 to thread2. But when thread3 is started in thread2, then it gives 1/2 of the time it has reserved for thread2 to thread3. So thread 3 has 1/4 of the time, thread2 as well, only thread1 still has 1/2 of the time. (of course i neglect here the time for switching between threads). But if I had started all three threads from the same main thread, then they would have the same amount of processor's time given. Please correct me if I'm wrong.
(ps. I assume that I start all threads with normal priority).

wysota
21st July 2010, 01:07
I dont wanna argue as I am a beginner, but it seems for me that in SOME way threads are nested - in the way how processor time is shared between them. Lets say I start one thread1, then start thread2 inside thread1 and then thread3 inside thread2. As I understand this, the processor gives 1/2 of the time it has for thread1 to thread2. But when thread3 is started in thread2, then it gives 1/2 of the time it has reserved for thread2 to thread3. So thread 3 has 1/4 of the time, thread2 as well, only thread1 still has 1/2 of the time.
No, that's not true. Of course there probably exist schedulers that act like that, on a general plane it wouldn't make any sense as thread1 would easily starve the other threads. Please remember threads are direct equivalents of processes (in some cases they are (or used to be) called "lightweight processes"). As a general rule we can treat two threads of the same process as two separate processes that share areas of their virtual memory. But back to processes... If we have a process (A) that spawns two other processes (B, C), process A can still operate while B and C are alive and there is (or at least doesn't have to be) no relation between slices of time assigned to each of them. Please consider an experiment - thread I starts threads II and III and III starts thread IV. So assuming your scenario thread I would get about 50% of the time, thread II would get roughly 25% of the time, and threads III and IV would get about 12.5% of the time (which immediately says IV is not "nested" into III as it has a similar time slice). So what would happen if thread I would block on some semaphore? Who would get the unassigned time and in what proportions? What would happen if then thread I would wake up and some other threads would go to sleep? And what happens if we have multiple CPUs? Scheduling processes (and threads) is not that simple :) The easiest (yet fully functional, with mandatory preemptive approach) scheduler is a round-robin where each thread gets an equal share of time one after another. Your approach could be implemented as an incarnation of a round-robin scheduler but it wouldn't be very effective - the shares would quickly go out of sync once threads started sleeping, just think about it.

Good schedulers try to use some heuristics when determining who should get the CPU. If one thread (process) mostly sleeps while waiting for I/O operations to finish it should probably get a different slice of CPU than a thread (process) that does some heavy calculations - regardless how many threads (processes) have been spawned by the "parent" process.

Ouch, that was a long explanation :) Hmm... my English is deteriorating but I'm to lazy to correct my post :(

huba
22nd July 2010, 20:01
Long explanation so I need a longer while to think about it:)

wysota
22nd July 2010, 21:21
Bear in mind it was 2 AM when I was writing it, it might not make any sense ;)