为什么single上,多线程中产生的对象不是同一个

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