COM的线程模型

5. COM中的线程
    Win32中的线程,典型的Win32程序具有两种不同类型的线程:用户界面线程和工作者线程。用户界面线程是同一个或者多个窗口关联着的,这些线程具有自己的消息循环,以便能对用户输入做出反应。工作者线程用于后台处理,它们没有任何窗口与之相关联,通常也没有消息循环。
    COM中使用的线程类型与Win32的两种类型的线程是相同的,只不过换了不同的名称而已。在COM中与Win32中的用户界面线程相对应是“套间线程”,而与工作者线程相对应的是自由线程。
    既然COM线程与Win32线程并没有什么差别,那么为什么COM还需要定义自己的线程呢?其原因在于参数调整与线程同步。
5.1 套间线程: 当线程调用CoInitializeEx时,使用参数 COINIT_APARTMENTTHREADED 时,此时这个线程就被称为是套间线程。
对于套间线程我们可以将其想象成一个用户界面线程。
① 我们知道一个用户界面线程将拥有所有在该线程中创建的窗口,同理一个套间线程将拥有所有它所创建的组件;
② 一个套间中组件只能由相应的套间线程来调用。如果某个线程给另外一个线程所拥有的窗口发送一条消息(SendMessage函数可以向不同线程中创建的窗口发送消息),Windows将把此消息放到那个窗口所在的线程消息队列中。窗口的消息循环将在创建此窗口的线程中执行。当消息循环取出一条消息并调用窗口过程时,此窗口过程也在,创建窗口的线程上运行。对于套间中的组件亦是如此,假设另一个线程调用一个套间中的某个组件的方法,COM库将把此请求放到套间的队列中。消息循环将取出此调用请求并在套间线程上执行相应的方法。通过这种消息调用机制,保证了套间中的组件只在相应的套间线程中被调用,也就是说不会出现多个线程并发访问这个组件的情况,因此组件就不需要考虑线程同步的问题了。
也就是说如果在某个时刻,一个线程是套间线程,则COM库将完成对组件的同步调用,实现方法:使用窗口的消息循环机制,将不同线程中的函数调用,封装成消息发送到套间线程,然后再套间线程中执行代码,从而保证,组件不会被并发访问。
5.2 自由线程:当线程调用CoInitializeEx时,使用参数 COINIT_MULTITHREADED 时,此时这个线程就被称为是自由线程。

5.3 一个线程不会固定的只是 套间线程或是 自由线程,因为一个线程可以多次进入不同的套间,当该线程进入的是单线程套间是此时这个线程就是套间线程,当该线程进入多线程套间时,这个线程就是自由线程。

5.4 单线程套间(single-threaded apartments)和多线程套间(multithreaded apartments)

前面我们描述的套间线程和自由线程,我们COM线程的角度来讨论的,现在我们从COM套间的角度来看看COM线程,其实如果一个线程某个时刻进入了一个COM单线程套间我们就称此线程此时是一个套间线程,如果一个线程在某个时刻进入了一个COM多线程套间我们就称此线程此时是一个自由线程。

看看MSDN中对单线程套间和多线程套间的描述:

5.5 线程模型的选择

posted @ 2014-03-07 23:10  a ray of sunshine  阅读(678)  评论(0编辑  收藏  举报