Chr*_*s J 7 vb6 com multithreading apartments
看看像MT一样的第一眼看到的东西,但我试图详细了解COM +使用的STA模型.
实际上,我有一个用VB6编写的遗留COM +组件,它调用用C++编写的本机(即非COM)Win32 DLL.
有一些间歇性(并且不可能在测试中重现)问题,我添加了一些调试代码来找出发生了什么,并发现当问题发生时,我在文件中交错了日志消息 - 所以它暗示了DLL被两个线程同时调用.
现在,日志记录转到基于_getpid()和GetCurrentThreadId()的每线程文件,所以看起来当调用C++ DLL中的代码时,它会在同一个线程上同时被调用两次.我对STA的理解表明,可能就是这种情况,因为COM将对象的各个实例编组到一个线程上,并随意恢复执行.
不幸的是,我不确定从哪里开始.我正在读我应该在DllMain()中调用CoInitialiseEx()告诉COM这是一个STA DLL,但其他地方说这只对COM DLL有效,并且在本机DLL中不会有任何影响.唯一的另一个选择是将DLL的一部分包装为关键部分以序列化访问(获取下巴上的任何性能命中).
我可以尝试重做DLL,但是没有共享状态或全局变量 - 一切都在局部变量中所以理论上每个调用应该得到自己的堆栈,但我想知道STA模型是否基本上对此有一些奇怪的影响并在与另一个调用相同的入口点重新进入已加载的DLL.不幸的是,我不知道如何证明或测试这个理论.
问题基本上是:
在单元线程 COM 服务器中,保证 COM 类的每个实例都可以由单个线程访问。这意味着该实例是线程安全的。但是,可以使用不同的线程同时创建许多实例。现在,就 COM 服务器而言,您的本机 DLL 不必执行任何特殊操作。想想 kernel32.dll,每个可执行文件都会使用它 - 当 COM 服务器使用它时,它会初始化 COM 吗?
从 DLL 的角度来看,您必须确保线程安全,因为不同的实例可以同时调用您。在这种情况下,STA 不会保护您。既然你说你没有使用任何全局变量,我只能假设问题出在其他地方,并且恰好在似乎指向 COM 内容的情况下出现。您确定没有一些普通的旧 C++ 内存问题吗?
| 归档时间: |
|
| 查看次数: |
1833 次 |
| 最近记录: |