为什么single下,多线程中产生的对象不是同一个?
- C/C++ code
为什么single下,多线程中产生的对象不是同一个?引子:CoCreateInstance这个函数,我记得是每次调用它,那么就产生一个工厂对象! 然后调用dllgetclassobject了, 这个函数最终产生了一个com对象。总结:如果两个线程中调用这个函数CoCreateInstance,那么产生的对象是不一样的。也就是说CoCreateInstance 与 com的线程模型与否毫无关系。正文(附代码)原作者提供这个代码,注意是single下的,他想证明一观念:如果在single下函数:CTestInterface1::TestFunc1 在两个线程中打印的结果不一样。所以举了这个例子。我很奇怪, 难道引子中的说法不对吗,如果对的话,那么这个例子就是在白忙活了。为什么引子里的东西不对呢?STDMETHODIMP CTestInterface1::TestFunc1(){ // TODO: Add your implementation code here std::cout << "In the itestinferface1''s object, the thread''s id is " << ::GetCurrentThreadId() << std::endl; return S_OK;}#define _WIN32_WINNT 0x0400#include < windows.h >#include < iostream >#include "..\TestComObject1\TestComObject1_i.c"#include "..\TestComObject1\TestComObject1.h"DWORD WINAPI ThreadProc(LPVOID lpv){ HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if ( FAILED(hr) ) { std::cout << "CoinitializeEx failed!" << std::endl; return 0; } ITestInterface1 *pTest = NULL; hr = ::CoCreateInstance(CLSID_TestInterface1, //look here 0, CLSCTX_INPROC, IID_ITestInterface1, (void**)&pTest); if ( FAILED(hr) ) { std::cout << "CoCreateInstance failed!" << std::endl; return 0; } hr = pTest->TestFunc1(); //here if ( FAILED(hr) ) { std::cout << "TestFunc1 failed!" << std::endl; return 0; } pTest->Release(); ::CoUninitialize(); return 0;}int main(int argc, char* argv[]){ HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if ( FAILED(hr) ) { std::cout << "CoinitializeEx failed!" << std::endl; return 0; } ITestInterface1 *pTest = NULL; hr = ::CoCreateInstance(CLSID_TestInterface1, //look here 0, CLSCTX_INPROC, IID_ITestInterface1, (void**)&pTest); if ( FAILED(hr) ) { std::cout << "CoCreateInstance failed!" << std::endl; return 0; } hr = pTest->TestFunc1(); //here if ( FAILED(hr) ) { std::cout << "TestFunc1 failed!" << std::endl; return 0; } DWORD threadID; HANDLE hThreads[1]; hThreads[0] = ::CreateThread(NULL, //创建一个进程 0, ThreadProc, (LPVOID)pTest, //将pTest作为一个参数传入新线程 0, &threadID); ::WaitForSingleObject(hThreads,INFINITE); //等待线程结束 ::CloseHandle(hThreads); //关闭线程句柄 pTest->Release(); ::CoUninitialize(); system("pause"); return 0;}[解决办法]
你想验证啥.
GetCurrentThreadId 返回的是调用这个函数的线程ID.
只要是多线程调用 TestFunc1 输出肯定是不一样.
你要验证是不是同一个对象, 你应该输出this指针.
[解决办法]
孩纸肯定不是同一个,你每CoCreateInstance一次就是一个新的组件对象。线程模型的区别,好像这么多年了也没有人把它说得更具体,很少有人见过源码不好具体说。从inside com的示例代码中看,感觉主要的区别在于组件对象是否存在于消息循环(窗口过程)中。
[解决办法]
线程首先会进入套间,Single创建一个只对本线程相关的新套间,套间内创建的对象本体在套间内,指针可以到处乱跑。
CoCreateInstance奇妙之处在于,IClassFactory是在SCM中注册的,InProc调用首先查询SCM是否有Cache,如果没有再创建Class Factory然后再创建Object instance返回interface.
对于每个CLSID,IClassFactory一般一个进程只有一个实例,而instance每个需要的套间都有。