From: kndg on 21 Jun 2010 06:30 On 6/21/2010 1:07 PM, Peter Duniho wrote: > [...] > Actually, there's no reason for an unmanaged (native) GUI program to > have more than one thread, assuming _only_ a dependency on the plain > Win32 GUI API. A GUI does not in and of itself imply an additional > thread; typically, the GUI executes in the same thread that the > process's initial entry point used. > Hi Pete, Thanks for your response. I had tried compiling it using the simplest code below, but Windows Task Manager shows it as having two threads. #include <windows.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lcCmdLine, int nCmdShow) { MessageBox(NULL, "Hi!", "Say Hi", MB_OK); return 0; } I'm no expert in Windows programming using Win32 API and I had already forgot how to coding it in C, but from the code above, clearly the MessageBox is called from the main thread which means that this program should have one thread only. But what the Task Manager reports make me think that there is something that cause the program to spawn another thread. Is it because MessageBox function call the COM component behind the scene? (I'm not familiar at all with COM object). Do you have an example that show a single threaded GUI program? [I'm sorry in advance as the above is not related to .Net at all - I'm just curious...] > A GUI application that uses COM components, especially those that are > free-threaded (i.e. use the multi-threaded apartment) may result in a > new thread started up by COM, because typically COM is initialized in > the main GUI thread as an STA thread. But even that will vary according > to the exact program. > > You _might_ also see one or more extra threads if running the process > under a debugger. But that's just an artifact of debugging. > >> For a .Net console application, there are at minimum four threads >> created. So, here is my own guess (I couldn't find a source on the >> internet to confirm this) >> >> 1. Native Win32 thread hosting the CLR >> 2. CLR (JIT, Assembly Loader and GC?) >> 3. ? or GC? >> 4. Primary AppDomain main thread > > The first thing to understand is that a native thread may or may not be > the same as a managed thread. So when counting threads, it's important > to make sure one is specific about which kind of thread one is talking > about. > > For example, in the above list, the "primary AppDomain main thread" is a > managed thread, while the "native Win32 thread hosting the CLR" is by > definition unmanaged. > > Beyond that, I would not expect the above list to be accurate even on > ..NET implementations where a managed thread corresponds exactly to an > unmanaged thread. In particular, the main thread for the managed process > is as far as I know the same as the main thread for the process. There's > certainly no obvious reason for it not to be, and even running under the > debugger (*), a .NET console app has only one non-worker thread. > > (*) where at least one additional thread is created as part of the > hosting mechanism�I did a test with a simple WPF application, which when > debugging had 6 threads without the debugger's host process and 13 with; > running standalone, it had only 5 threads > I'm checking the thread count using the Process class by enumerating the Threads property. So, it is probably a total of unmanaged and managed threads. Coupled with the info from Task Manager, and since current implementation of managed thread in .Net maps directly to unmanaged thread, I assume the figure I get is correct. When I run a simple WPF application, initially I got 10 threads, but over the time it reduced to 7 threads and then up back to 8 threads and then down again but never below than 7. So, I think as you said the 3 threads probably comes from the thread pool. But that leaves the other two mysterious. >> Actually, at first I thought that the GC would be on the same thread >> as the CLR thread and left the third mysteriously unknown (to myself), >> but after researching on the internet, I found that the GC is actually >> running concurrently and running on their own thread and that fills my >> mysterious thirds thread. And since you had mentioned it, it probably >> affirms my own guess. > > The GC can be run concurrently or not, depending on .NET implementation > and configuration. > Ok, I will check on how to configure that and observe whether the thread count will be effected or not. >[...] > I don't actually know what all the different threads .NET and its > various components may create on the behalf of the process actually do. > The fact is, it's not something I worry about very much. The exact > thread count for a managed process is even more of an "implementation > detail" than for an unmanaged process, and even the unmanaged process > has some specific scenarios where you might get a thread or two in your > process you didn't explicitly create. > Yes, I agree. I'm just exploring it simply for my own curiosity. Regards.
From: Peter Duniho on 22 Jun 2010 02:40 kndg wrote: > I had tried compiling it using the simplest code below, but Windows Task > Manager shows it as having two threads. > > #include <windows.h> > > int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR > lcCmdLine, int nCmdShow) > { > MessageBox(NULL, "Hi!", "Say Hi", MB_OK); > > return 0; > } Well, I can't explain what you're observing. However, when I compile the above, Task Manager shows the process has having just one thread. As it does also if I just create a new project using the built-in Win32 project template. I don't doubt you're seeing a second thread, but whatever that thread is, it's coming from something other than the basic process stuff that normally goes on. > I'm no expert in Windows programming using Win32 API and I had already > forgot how to coding it in C, but from the code above, clearly the > MessageBox is called from the main thread which means that this program > should have one thread only. But what the Task Manager reports make me > think that there is something that cause the program to spawn another > thread. Is it because MessageBox function call the COM component behind > the scene? (I'm not familiar at all with COM object). There shouldn't be any COM stuff going on in the code you showed. But then, you also should only be seeing a single thread in Task Manager. So who knows? > Do you have an example that show a single threaded GUI program? Yes. You posted it. :) > I'm checking the thread count using the Process class by enumerating the > Threads property. So, it is probably a total of unmanaged and managed > threads. The Process.Threads property returns "ProcessThread" objects, which represent _only_ OS threads, not managed threads. The length of the array returned by the Threads property will be the count of the OS threads and will have no direct relationship to managed threads at all (though of course on the normal workstation client implementations of ..NET, a single managed thread is hosted in a single OS thread�but as I mentioned before, you can't count on this). > Coupled with the info from Task Manager, and since current > implementation of managed thread in .Net maps directly to unmanaged > thread, I assume the figure I get is correct. I agree that if you're running .NET on your desktop computer, with no special configuration changes, the count of threads returned by Process.Threads should be the same as the count of managed threads. But that's practically just coincidence. Pete
From: kndg on 22 Jun 2010 05:32
On 6/22/2010 2:40 PM, Peter Duniho wrote: > kndg wrote: >> I had tried compiling it using the simplest code below, but Windows >> Task Manager shows it as having two threads. >> >> #include <windows.h> >> >> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR >> lcCmdLine, int nCmdShow) >> { >> MessageBox(NULL, "Hi!", "Say Hi", MB_OK); >> >> return 0; >> } > > Well, I can't explain what you're observing. However, when I compile the > above, Task Manager shows the process has having just one thread. As it > does also if I just create a new project using the built-in Win32 > project template. > > I don't doubt you're seeing a second thread, but whatever that thread > is, it's coming from something other than the basic process stuff that > normally goes on. > Arghh, I should have try this on different computer... Yes, you are right. They are all just shows as one thread (XP/Vista/Win7). Hmm... probably it is just the problem with my system. My first thought was trojan, but a quick debugging session tells me unlikely (the second thread just make harmless (probably) calls to the system library). Anyway, I would try not to go deeper than this (my head seems like to crack..) Thank you for your helpful response as always. Regards. |