MSXML在多线程成使用中发生错误

solomonlxd 2011-12-20 04:51:40
一个压力测试工具,线程数可控,每个线程中都会对同一个IXMLDOMDocument进行操作,当线程少的时候,比如100个,很少会出现问题,但是当线程数超过200,每次运行很快就会出现异常:
PowerTest_D.exe 中的 0x5880e921 处未处理的异常: 0xC0000005: 读取位置 0x00000008 时发生访问冲突
产生异常的代码每次都是对某个IXMLDOMNode的调用,比如selectSingleNode或者selectNodes,此时该IXMLDOMNode对象不为空,我认为是MSXML内部出现了问题,请问如何解决这个问题?

我的IXMLDOMDocument初始化代码:


MSXML2::IXMLDOMDocumentPtr m_pXmlDoc;
HRESULT hr = CoCreateInstance(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument2, (void**)&m_pXmlDoc);


不用CLSID_DOMDocument60改用CLSID_DOMDocument40或CLSID_DOMDocument都是一样的现象。
...全文
79 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
solomonlxd 2011-12-21
  • 打赏
  • 举报
回复
专门做了个测试程序,主线程中初始化DOC:

#define LPXMLDOC MSXML2::IXMLDOMDocumentPtr
#define LPXMLELEMENT MSXML2::IXMLDOMElementPtr
#define LPXMLNODE MSXML2::IXMLDOMNodePtr
#define LPXMLNODES MSXML2::IXMLDOMNodeListPtr
#define LPXMLPI MSXML2::IXMLDOMProcessingInstructionPtr
#define LPXMLCDATA MSXML2::IXMLDOMCDATASectionPtr
#define LPXMLERROR MSXML2::IXMLDOMParseErrorPtr


CString strFile = "D:\\Work\\PowerTest\\PowerTest\\Bin\\1.xml";
HRESULT hr = m_pXmlDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));
if(hr != S_OK || m_pXmlDoc == NULL)
return;
m_pXmlDoc->load(_bstr_t(strFile));

然后创建1500个线程,在线程中:

HRESULT hr = CoInitialize(NULL);
if(hr != S_OK)
{
AfxMessageBox("COM初始化错误!");
return FALSE;
}

LPXMLNODE pRootNode = theApp.m_pXmlDoc->selectSingleNode(_bstr_t("PowerTest"));
LPXMLNODE pSettingNode = pRootNode->selectSingleNode(_bstr_t("BaseSettings"));
LPXMLNODE pMonitorNode = pSettingNode->selectSingleNode(_bstr_t("Monitor"));
LPXMLNODE pSessionNode = pMonitorNode->selectSingleNode(_bstr_t("Session"));
LPXMLNODE pColumnRoot = pSessionNode->selectSingleNode(_bstr_t("ColumnSetting"));
LPXMLNODES pColumnNodes = pColumnRoot->selectNodes(_bstr_t("Column"));
long nCount;
pColumnNodes->get_length(&nCount);
for(long i=0;i<nCount;i++)
{
LPXMLNODE pColumnNode;
pColumnNodes->get_item(i, &pColumnNode);
LPXMLELEMENT pColumnElement = pColumnNode;
_variant_t varName = pColumnElement->getAttribute(_bstr_t("ListColumnName"));
_variant_t varWidth = pColumnElement->getAttribute(_bstr_t("ListColumnWidth"));
}

然后多次执行,有时就会出现错误,错误位置可能在任何一个XML操作语句
solomonlxd 2011-12-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 gw_net 的回复:]

抓个dump看看access violation在哪,
[/Quote]
异常出在selectSingleNode或者selectNodes代码内部
solomonlxd 2011-12-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dream238 的回复:]

引用 3 楼 solomonlxd 的回复:

引用 2 楼 dream238 的回复:
每个线程里的IXMLDOMDocument都是新的对象吗?线程里有没有做COM的初始化?

IXMLDOMDocument对象只有一个,每个线程一开始就调用了CoInitialize(NULL)进行COM初始化


多线程用一个接口?如果是这样的话,注意做好同步操作。
[/Quote]

因为MSXML应该是支持多线程使用的,其内部已经做了同步的工作,我自己另外创建一个信号量来完成同步问题完全没有改善
ArcRain 2011-12-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 solomonlxd 的回复:]

引用 2 楼 dream238 的回复:
每个线程里的IXMLDOMDocument都是新的对象吗?线程里有没有做COM的初始化?

IXMLDOMDocument对象只有一个,每个线程一开始就调用了CoInitialize(NULL)进行COM初始化
[/Quote]

多线程用一个接口?如果是这样的话,注意做好同步操作。
gw_net 2011-12-20
  • 打赏
  • 举报
回复
抓个dump看看access violation在哪,
solomonlxd 2011-12-20
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dream238 的回复:]
每个线程里的IXMLDOMDocument都是新的对象吗?线程里有没有做COM的初始化?
[/Quote]
IXMLDOMDocument对象只有一个,每个线程一开始就调用了CoInitialize(NULL)进行COM初始化
ArcRain 2011-12-20
  • 打赏
  • 举报
回复
每个线程里的IXMLDOMDocument都是新的对象吗?线程里有没有做COM的初始化?
oyljerry 2011-12-20
  • 打赏
  • 举报
回复
如果它自身有这个bug,那么你就要来规避了,比如不开这么多线程
可以尝试给微软提交bug

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧