I reproduced an article about the com thread model some time ago. I felt that the effect was still very general. Later I collected some information and planned to write an article that is very easy to understand, this is an accurate article.
Generic "com thread model": http://blog.csdn.net/guogangj/archive/2007/09/06/1774280.aspx
The Chinese Translation of apartment is "apartment", and sometimes it is "Suite". Here it is translated as "apartment". It all means the thread mode of COM, this concept is abstract and difficult to understand. Because the apartment does not have a "handle" like the Windows kernel object, and there are very few windows APIs related to the apartment, there are only five: coinitialize, couninitialize, coinitializeex, oleinitialize and oleuninitialize, everyone is familiar with the following five functions: COM Initialization and anti-initialization. How can we understand apartments? It can be like this: 1. The thread lives in the apartment; 2. The object lives in the apartment. Sometimes, the object and the thread that created it live in the same apartment, sometimes not. This is hard to understand, right? But it's okay. Remember this first and you will understand it later.
Com only has two types of apartments, one is single-thread apartment (STA), and the other is multi-thread apartment (MTA, one can only accommodate one thread, and the other can accommodate multiple threads. In a process, there is only one MTA, and there can be many Stas.
Before using COM, we should initialize com first. How should we initialize it? Of course, the above mentioned functions, coinitialize, coinitializeex and oleinitialize, are we initializing every program (process) or every thread? The answer is the thread. Every thread is initialized once. Such Initialization is equivalent to placing this thread in an apartment. Specifically, coinitialize or oleinitialize puts the thread into the sta; coinitializeex allows you to place the thread into the MTA. The methods for removing threads from an apartment are couninitialize and oleuninitialize.
We all know that an object is created by a thread. When is the object the same as the thread that created it, and when is it not the same apartment? As mentioned above, the apartment type where the thread is located is determined by the initialization functions. What determines the apartment where the object is located? This is a little more complex. The answer is: it is determined by the thread type of the created thread and the thread attribute of the object. As we all know about the thread type, the initialization functions mentioned above are used to determine the thread attribute of the object itself? Answer: set the information in the registry.
Open the Registry Editor and follow the path: "/hkey_classes_root/CLSID/{00000010-0000-0010-8000-00aa006d2ea4}/inprocserver32" (this GUID is strange, obviously not generated by a tool, microsoft can manually enter the guid privilege.) Check the value of "threadingmodel". Well, yes, it's "apartment ", this "apartment" is the "thread attribute of the object itself" I mentioned just now. There are four types of thread attributes of the object: apartment, both, free, and single. The following table is displayed at a glance.
Component thread attribute | stathread | MTA thread
Bytes --------------------------------------------------------------------------------------
Apartment | in the same apartment, access directly | create a sta and use a proxy to access
Free | MTA, accessed by proxy | MTA, direct access
Both | in the same apartment, direct access | MTA, direct access
Single | in the master STA, access through the master sta
Note: The first thread that calls coinitializeex () with coinit_apartmentthreaded is called the master Sta.
For example, if a stathread creates an object whose thread attribute is free, the object exists in MTA and the stathread accesses it through proxy. Of course, this is transparent to programmers, because this function is implemented by the remoting layer of COM. What is different from direct access? It may be that access through proxy is slow. After all, messages need to be stored in alling, however, the time difference between those milliseconds is hard for us (j ).
Obviously, as long as we set the component type to apartment, there will be no thread access conflict issues.