void __stdcall test()
{
::CoInitialize(NULL);
_ConnectionPtr pconn;
pconn.CreateInstanse( __uuidof(Connection));
pconn.Open(...);
pConn.Close();
pConn.Release();
::CoUninitialize();
}上面这个函数是动态库里面的一个接口函数,省略了一些try语句,open中的参数是对的,也就是能够open成功。该函数被同一线程调用多次后,为什么会出问题啊?
一般第一次好像没什么问题,后面的调用就会报一个“读取位置 0x4a1b6b45 时发生访问冲突”之类的错误。
初步验证了函数中要是去掉
pconn.Open(...);
pConn.Close();
这两句的话,调用是没有问题的。
今天灵感来了^^
考虑到每次挂掉的时候,没有运行任何用户代码,故我认为_ConnectionPtr的Close()与Release()是异步函数
在Close()或Release()没有充分执行完成就调用::CoUninitialize(),将会产生上述的错误。
于是我在::CoUninitialize()前加上一条Sleep(500),问题不出现了!!!问题是否已经解决了,等我在虚拟机上试了再作定论吧...
暂且这样认为:调用Close()与Release()释放连接是需要时间的,这在性能不好的机器上(包括虚拟机)就表现为连接资源还在释放过程当中(我认为是异步释放),但线程已经开始调用CoUninitialize()了,这势必产生问题;故在性能好的机器上基本上没有问题的现象就可以解释了。解决办法就是在CoUninitialize()调用之前让线程切换去继续释放连接资源,Sleep()一下是不错的选择。谢谢saylerboxer 和marrco2005的关注