I used the NameThreadForDebugging in my application to name all my custom threads and even a main thread.
Now I see in Delphi IDE's Threads window seven threads. Three of them are my threads, but four other have no names and contain following call stacks:
Thread 1
ntdll.NtWaitForMultipleObjects
kernel32.BaseThreadInitThunk
ntdll.RtlInitializeExceptionChain
ntdll.RtlInitializeExceptionChain
Thread 2
ntdll.NtWaitForWorkViaWorkerFactory
kernel32.BaseThreadInitThunk
ntdll.RtlInitializeExceptionChain
ntdll.RtlInitializeExceptionChain
Thread 3
ntdll.NtWaitForMultipleObjects
kernel32.WaitForMultipleObjectsEx
C:\Windows\syswow64\USER32.dll
USER32.MsgWaitForMultipleObjects
etc.
They aren't TTimer objects because timers do not produce separate threads. What are they?
Those threads are associated with a threadpool, specifically the TpWorkerFactory object manager introduced with Windows Vista. NtWaitForWorkViaWorkerFactory (in thread #2) is part of the internal implementation of the threadpool and the other two threads are most likely worker threads which belong to the threadpool.
In the RTL these are almost certainly default objects created to implement the PPL functionality introduced in the System.Threading unit.
Related
I am reading Inside COM by Dale Rogerson, and it uses the terms apartment threads and free threads to describe the different types of COM threads.
He also clarifies that these correspond directly to UI threads and worker threads:
COM uses the same two types of threads, although COM has different names for them. Instead of calling one a user-interface thread, COM uses the term apartment thread. The term free thread is used instead of worker thread. [...]
However, lots of other documentation refers to STAs and MTAs. "Single-Threaded Apartments" and "Multi-Threaded Apartments."
Do "apartments/free threads" and "STA/MTA" mean different things? Does Rogerson's book (1997) no longer reflect COM's threading model?
Why has the naming changed?
Disclaimer: I work for Microsoft.
It seems that the terms are interchangeable:
COM synchronizes calls
COM does not synchronize calls
STA (preferred name)
MTA (preferred name)
"Apartment thread"
Free thread
(often) UI thread
(often) Worker thread
Descriptions and workings of OLE threading models indicates STA == apartment thread and MTA == free thread (even though both new terms use the word "apartment"):
Single-threaded Apartment model (STA): One or more threads in a process use COM and calls to COM objects are synchronized by COM. Interfaces are marshaled between threads. A degenerate case of the single-threaded apartment model, where only one thread in a given process uses COM, is called the single-threading model. Previous have sometimes referred to the STA model simply as the "apartment model."
Multi-threaded Apartment model (MTA): One or more threads use COM and calls to COM objects associated with the MTA are made directly by all threads associated with the MTA without any interposition of system code between caller and object. Because multiple simultaneous clients may be calling objects more or less simultaneously (simultaneously on multi-processor systems), objects must synchronize their internal state by themselves. Interfaces are not marshaled between threads. Previous have sometimes referred to this model as the "free-threaded model."
And as quoted above apartment thread == UI thread and free thread == worker thread according to Rogerson:
COM uses the same two types of threads, although COM has different names for them. Instead of calling one a user-interface thread, COM uses the term apartment thread. The term free thread is used instead of worker thread. [...]
I'd love to know why the terminology changed, though.
May I know JVM handles Thread scheduling? How JVM handles unused threads (i.e) Threads that are not in running state. Does too much of unused threads is burden to JVM?
This is rather an open-ended question but I'll give you a quick synopsis.
Java has always had the concept of threads in the language. Sometimes these map to OS threads but, where an OS does not support them (like Windows 95), the JVM can implement its own threading layer called green threads. Today you can ignore green threads so the lowest level scheduling of JVM threads is handled by the OS.
However, all Java threads have a priority associated with them which allows you to signal to the JVM and OS which threads you consider to be more important than others in the context of scheduling. This is a property of the Thread class and is accessed with getPriority/setPriority. There are rules about how this value can be changed according to the security policy and the maximum thread priority. Changing thread priorities to implement specific application behaviour is not recommended due to the different way platforms implement thread scheduling.
Java and the JVM make no guarantees about when threads will be scheduled. When there is competition for processing resources, threads with higher priority are generally executed in preference to threads with lower priority. Importantly, this is not a guarantee that the highest priority thread will always be running. Thread priorities should not be used (or relied on) to implement mutual exclusion.
Unused threads will be garbage collected just like any other objects. Because Threads are heavyweight objects that take time to create and remove, an application that intends to use lots of short-lived threads will typically implement some sort of thread pooling. Too many threads will place a burden on the JVM, more so than other objects, because of the link to the underlying OS threads.
For more detailed information on Java threads and concurrency, I recommend reading Brian Goetz's excellent book, "Java Concurrency in Practice".
I have a conceptual question about multithreading:
In a application using RPC through DCOM, with multithread appartment configuration, the main form is freezing.
1 - If the CriticalSession is created in the unit initialization, the code in the critical session will run in the main thread context?
2 - When you call the method to execute a task:
Thread 1 is created. (DCOM Thread)
Thread 1 creates Thread 2.
Thread 1 WaitFor Thread 2.
Thread 2 creates 4 thread to run the task faster.
Thread 2 loops sleeping 2 seconds until the end of the 4 threads. In this processes the main form is supposed to be refreshed to display the percent done. A message is posted to the main form thread with the percent done, but nothing happens and the main form is freezed.
3 - There is a better way instead of synchronized() method, to synchronize inside one of the 4 threads when they need to CRUD (Create Read Update Delete) objects in the Thread 2?
4 - The 4 Threads have higher priority then the main thread is this a problem? When this become a problem?
The image below represent the architecture of the system:
1: No. By using a cricital section, you guarantee the code is run in only one thread at a time; in practice any thread that calls Enter will hang there until any other thread that is also running that code gets to the Leave call. But this doesn't mean it will run in the main thread (check with GetCurrentThreadID)
2: You mention apartment configuration, but which apartment threading model? This defines when (D)COM will do thread synchronzation for you. In practice COM will work with proxy stubs and marshalling behind the scenes to traverse apartment (and network) boundaries, unless you've selected multi threaded apartment, in which case COM will suppose the components take care of threading issues by themselves.
If I understand correctly, the main form freezes on the 'Thread 1 WaitFor Thread 2'. Instead of calling WaitFor you'll be better off using the OnTerminate event on Thread2.
3: I'm not sure what you mean by 'CRUD objects in Thread 2'. If it is not important to know in what order the 4 threads finish, I would suggest to call WaitFor on the threads in sequence. If it is, you should check out WaitForMultipleObjects.
4: Different priorities should not be a problem. It only might be a problem when there are too much high-priority threads doing too much work so the normal-priority threads doing internal communication can't keep up, but in that case you should review how worker threads report their work.
I don't quite understand the difference between threads and lightweight threads. From an API perspective both types of threads are identical so where exactly does the difference come in. Is it at the implementation level where a lightweight thread is managed by a higher level runtime than the OS thread scheduler or is it something else? Also, is there set of heuristics that people use to decide which type of thread to use in specific scenarios?
In what context, lightweight threads could represent threads which are implemented by a library, for example threads can be simulated in a library by switching between lightweight threads at an event handling layer, these lightweight threads are queued up and processed by a singe OS thread, the advantage of this is that since context switching is handled in the library switching can occur when the processing of data is complete and so the data does not need to be loaded back into the CPU's cache next time this lightweight thread becomes active.
Lightweight threads could also refer to co-operative threads (or fibers), these are threads where you have to explicitly yield to give other lightweight threads a chance, this has the same advantage in that the context switching can occur at a place you know you have finished processing some data and so you know it will not be need again.
Alternativly Lightweight threads could mean normal OS threads and the non-lightweight threads could mean processes, process have at least one thread within them and also have there own memory and other resources, they are more expensive than threads because you can not share data between thread easily and it can be a more expensive operation for the OS to create processes.
Is there any comprehensive overview somewhere that discusses all the different types of threads and what their relationship is with the OS and the scheduler? I've heard so much contradicting information about whether you want certain types of threads, or whether thread pooling is a performance gain or a performance hit, or that threads are heavy weight so you should use these other kind of threads that don't map directly to real threads but then how is that different from thread pooling .... I'm paralyzed. How does anyone make sense of it? Assuming the use of a language that actually directly interacts with threads (I'm aware of concurrent languages, implicit parallelism, etc. as an alternative to needing to know this stuff but I'm curious about this at the moment)
Here is my brief summary, please comment and edit at will:
There are no hyperthreads, unless you're talking about Intel's hyperthreading in which case it's just virtual cores.
"Green" usually means "not OS-level" (scheduled/handled by a VM, which may or may not map those unto multiple OS-level threads or processes)
pthreads are an API (Posix Threads)
Kernel threads vs user threads is an implementation level (user threads are implemented in userland, so the kernel is not aware of them and neither is its scheduler), "threads" alone is generally an alias for "kernel threads"
Fibers are system-level coroutines. They're threads, except cooperatively multitasked rather than preemptively.
Well, like with most things, it's common to not just care unless threading is identified as a bottleneck. That is, just use the threading functionality that your platform provides in the usual manner and don't worry about the details, at least in the beginning.
But since you evidently want to know more: Usually, the operating system has a concept of a thread as a unit of execution, which is what the OS scheduler handles. Now, switching between OS-level threads requires a context switch, which can be expensive and can become a performance bottleneck. So instead of mapping programming-language threads directly to OS threads, some threading implementations do everything in user space, so that there is only one OS-level thread that is responsible for all the user-level threads in the application. This is more efficient both performance- and resource-wise, but it has the problem that if you actually have several physical processors, you cannot use more than one of them with user-level threads. So there's one more strategy of allocating threads: have multiple OS-level threads, the number of which relates to the number of physical processors you have, and have each of these be responsible for several user-level threads. These three strategies are often called 1:1 (user threads map 1-to-1 to OS threads), N:1 (all user threads map to 1 OS thread), and M:N (M user threads map to N OS threads).
Thread pooling is a slightly different thing. The idea behind thread pooling is to separate the execution resources from the actual execution, so that you have a number of threads (your resources) available in the thread pool, and when you need some task to be executed, you just pick one thread from the pool and hand the task over to it. So thread pooling is a way to design a multi-threaded application. Another way to design would be to identify the different tasks that will need to be performed (e.g., reading from a network, drawing the UI to the screen), and create a dedicated thread for these tasks. This is mostly orthogonal to whether the threads are user- or OS-level concepts.
Threads are the main building block of a Process in the Windows win32 architecture. You can ignore green threads, fibers, green fibers, pthreads (POSIX). Hyper threads don't exist. It is "hyper threading" which is a CPU architecture thing. You cannot code it. You can ignore it.
This leaves use with threads. Indeed. Only threads. A kernel thread is a thread of the kernel, which lives in the upper 2GB (sometimes upper 1GB) of the virtual memory addess space of a machine. You cannot touch it. So you can ignore it most of the time (unless you are writing kernel mode ring-0 code).
Only user threads are the ones you should be concerned about. They come in two flavors: main thread and auxiliary threads. Each process has at least one main thread, it is created for you when you create a process (CreateProcess API call). Auxiliary threads can do tasks that take long and otherwise interrupt the user experience. In C#/,NET you can use the BackgroundWorker class to easily create and manage threads.
Threads have several properties. This may have lead to all "kinds" of threads. But worker threads are probably the only ones you should be worried about when you start dealing with threads.
I learned a lot reading these slides.
I came across this after looking at Unicorn.