COM的套间与线程

    技术2026-04-11  1

    最近学习COM的编程,开发工具是VC6.0的ATL。

    用两个线程进行测试,主线程(Main Thread)和一个新开的线程(New Thread)。两个线程实例化的同一个COM组件。

    主要测试的是COM的套间,套间主要是规范对象和线程之间的关系,不在同一个套间的线程和对象,线程不能直接访问。

    以下是各种情况下的测试。

    一:Main Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)

          New Thread:CoInitialize(NULL)

          对象线程模型:Single

     

    Main Thread ID:4156 Object Pointer:1447804 COM OBJECT's THreadID:2880 New Thread ID:5920 Object Pointer:18897832 COM OBJECT's THreadID:5920

     

    二:Main Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)

          New Thread:CoInitialize(NULL)

          对象线程模型:Apartment

     

    Main Thread ID:2288 Object Pointer:1447804 COM OBJECT's THreadID:5316 New Thread ID:2496 Object Pointer:18897832 COM OBJECT's THreadID:2496

    三:Main Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)

          New Thread:CoInitialize(NULL)

          对象线程模型:Free

    Main Thread ID:4912 Object Pointer:4152232 COM OBJECT's THreadID:4912 New Thread ID:5396 Object Pointer:1437828 COM OBJECT's THreadID:5400

     

    四:Main Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)

          New Thread:CoInitialize(NULL)

          对象线程模型:Both

     

    Main Thread ID:4964 Object Pointer:4152232 COM OBJECT's THreadID:4964 New Thread ID:5920 Object Pointer:11230120 COM OBJECT's THreadID:5920

    五:Main Thread:CoInitialize(NULL)

          New Thread:CoInitialize(NULL)

          对象线程模型:Apartment

     

    Main Thread ID:5364 Object Pointer:10181544 COM OBJECT's THreadID:5364 New Thread ID:5368 Object Pointer:11230120 COM OBJECT's THreadID:5368

     

    六:Main Thread:CoInitialize(NULL)

          New Thread:CoInitialize(NULL)

          对象线程模型:Single

     

    Main Thread ID:5884 Object Pointer:10181544 COM OBJECT's THreadID:5884 New Thread ID:1752 Object Pointer:11230120 COM OBJECT's THreadID:1752

     

    七:Main Thread:CoInitialize(NULL)

          New Thread:CoInitialize(NULL)

          对象线程模型:Free

     

    Main Thread ID:5068 Object Pointer:1437380 COM OBJECT's THreadID:5580 New Thread ID:4528 Object Pointer:1425180 COM OBJECT's THreadID:5992

     

    八:Main Thread:CoInitialize(NULL)

          New Thread:CoInitialize(NULL)

          对象线程模型:Both

     

    Main Thread ID:4216 Object Pointer:10181544 COM OBJECT's THreadID:4216 New Thread ID:1524 Object Pointer:11230120 COM OBJECT's THreadID:1524

     

    九:Main Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)

          New Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)

          对象线程模型:Free

     

    Main Thread ID:5960 Object Pointer:4152232 COM OBJECT's THreadID:5960 New Thread ID:5212 Object Pointer:4152232 COM OBJECT's THreadID:5212

     

    只有第九种情况的时候,两个线程访问的是同一个对象。

    为了了解不同情况下的对象调用步骤,这两天使用windbg,对调用过程进行了单步跟踪(跨线程的调用过程太麻烦了,没有跟踪完

    ,呵呵,只是看到RPC调用的处理),所以以下的结论是的的确确的哦。

    套间分为STA和MTA两种,COM组件的线程模型由single、apartment、free、both四种指定(测试没有发现single和apartment的区别,难道是遗留分类,后来已经一样了),STA包括single、apartment、both ,MTA包括free、both,和对象相同套间类型线程才能够直接加载对象,否则需要通过RPC跨线程进行访问,参数也需要进行特殊处理(marshal)才能够传递。

    需要特殊处理的是多个Free线程加载Free对象,这时这些个Free线程访问的是同一个Free对象,需要进行同步处理。

     

    以上是我这两天的成果,针对的是进程内COM对象调用,下一步研究跨进程调用。

    最新回复(0)