为什么single上,多线程中产生的对象不是同一个
为什么single下,多线程中产生的对象不是同一个?
------解决方案--------------------
你想验证啥.
GetCurrentThreadId 返回的是调用这个函数的线程ID.
只要是多线程调用 TestFunc1 输出肯定是不一样.
你要验证是不是同一个对象, 你应该输出this指针.
------解决方案--------------------
孩纸肯定不是同一个,你每CoCreateInstance一次就是一个新的组件对象。线程模型的区别,好像这么多年了也没有人把它说得更具体,很少有人见过源码不好具体说。从inside com的示例代码中看,感觉主要的区别在于组件对象是否存在于消息循环(窗口过程)中。
------解决方案--------------------
线程首先会进入套间,Single创建一个只对本线程相关的新套间,套间内创建的对象本体在套间内,指针可以到处乱跑。
CoCreateInstance奇妙之处在于,IClassFactory是在SCM中注册的,InProc调用首先查询SCM是否有Cache,如果没有再创建Class Factory然后再创建Object instance返回interface.
对于每个CLSID,IClassFactory一般一个进程只有一个实例,而instance每个需要的套间都有。
- 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每个需要的套间都有。