读书人

为什么single上多线程中产生的对象不

发布时间: 2012-11-08 08:48:11 作者: rapoo

为什么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每个需要的套间都有。

读书人网 >VC/MFC

热点推荐