Groups | Blog | Home
all groups > dotnet clr > february 2004 >

dotnet clr : Understanding threading model


Mark J.
2/23/2004 11:21:05 PM
Hi,

I've been doing some experiments to better understand threading within an app domain, and I have a couple of questions perhaps you guys could help me with...

The MSDN docs point out that as long as there are foreground threads an application will not terminate. Although I can't find any mention of it in the docs, an application's main thread appears to be special. Am I correct in saying that:

- An application will never terminate until it's main thread has completed.
- If the main thread is an app's only thread, and it's set as a background thread, it will still run to completion.
- It seems impossible to ever "Join()" the main thread from a spawned thread, even if the spawned thread is a foreground thread, and the main a background thread.

So from the CLR's point of view, as long as the main thread's around, the app's alive, and if the main thread finishes its work and there are no other foreground threads around then the app is done?

Is it also true to say that the presence of STA and MTA apartment attributes have zero effect on the thread behavior in a managed app that doesn't interop with COM?


Thanks all,

Valery Pryamikov
2/24/2004 10:31:30 AM
Hi,

I see that you mixed it all up :-). Here I just want to put some points in
place:

<Win32>

In Win32 main thread is the thread that is started with application. This is
the only meaning of this thread for operative system. Otherwise it isn't
different than any other thread created inside the process. The process will
stay alive until it has at least one running thread or ExitProcess (or
TerminateProcess) API is called.

C/C++ library puts ExitProcess call at the end of your main thread after
exit from your program's entry point therefore caused some common
misinterpretation that process will terminate when main thread terminates.
This is wrong and could be easily proved otherwise by making simple program
that starts a thread and exits main. After that you can start it in
debugger, step out of main, step until you will see call to ExitProcess and
just set execution pointer to the next instruction after ExitProcess call
(ie terminate main thread without ExitProcess). After that your program will
run as long as your second thread will be running. Other languages simply
followed practice of C/C++ libraries and added ExitProcess at the end of
main thread, because it became expected program behavior...

</Win32>

<dotNet>

..Net added notion of background and foreground threads. Main idea was that
process will be running as long as it has at least one foreground thread
running. But for implementing that they need a place to wait for all
foreground thread to be signaled and call ExitProcess. Most obvious place
for this wait is GC thread, but I never actually verified that.

If there will be any alive background tread at the point when all foreground
thread become signaled, these background threads doesn't matter anymore as
they will be terminated by the ExitProcess (just as standard C/C++ program
terminates after you exit program entry point).

</dotNet>

<COM_Interop>

STA and MTA (+NTA and main threading model) are only related to COM objects
hosting and COM interfaces marshalling rules and aren't related to the
thread life time at all...

</COM_Interop>



-Valery



See my blog at:

http://www.harper.no/valery



[quoted text, click to view]
app domain, and I have a couple of questions perhaps you guys could help me
with...
[quoted text, click to view]
application will not terminate. Although I can't find any mention of it in
the docs, an application's main thread appears to be special. Am I correct
in saying that:
[quoted text, click to view]
thread, even if the spawned thread is a foreground thread, and the main a
background thread.
[quoted text, click to view]
app's alive, and if the main thread finishes its work and there are no other
foreground threads around then the app is done?
[quoted text, click to view]
attributes have zero effect on the thread behavior in a managed app that
doesn't interop with COM?
[quoted text, click to view]

cbrumme NO[at]SPAM microsoft.com
3/3/2004 2:50:18 PM
The distinction between foreground and background threads only applies if
the EXE that kicks off the process is a managed EXE. In all other cases,
foreground vs. background is irrelevant.

For the case where a managed EXE kicks off the process, we will terminate
the process when all foreground threads have terminated. We use the 'main'
thread of the EXE to wait until this condition is true. That's why a Join
of the main thread is never satisfied in this case. This is an
implementation detail, and during Whidbey we toyed with the idea of
cleaning it up a little. Ultimately, I decided that the churn was not
worth the incremental improvement, particularly since it ran the risk of
breaking existing applications.

As for STA vs. MTA, the CLR's behavior is indeed different even if the
thread does not interact with COM. Specifically, any managed blocking on
the thread will include a certain amount of pumping if the thread is an STA
thread. This is the case even if you never make a COM call. You can read
the full details of this at
http://blogs.msdn.com/cbrumme/archive/2004/02/02/66219.aspx.


Valery Pryamikov
3/3/2004 7:58:59 PM
[quoted text, click to view]



Chris,



I feel a bit embarrassed to write this (after all English is my third
language, therefore it might be that I totally misunderstood the tone of
your letter), however I got an impression that you were arguing to something
that I wrote in my letter. However, the only thing that I found different
was information about where managed exe waits for foreground threads to
terminate, but I clearly stated that I was speculating about this... The
rest was just extra details and some details that were expressed in
different words...



Regards,

-Valery.



cbrumme NO[at]SPAM microsoft.com
3/4/2004 2:30:33 PM
Unfortunately I have no such excuse. English is my first language.
Nothing I wrote was intended to be argumentative. I agree that most of
what I wrote simply confirmed what you had already stated. Looking back at
my words, it's clear I should have introduced the post with "Valery is
correct..."
AddThis Social Bookmark Button