这两天在做一个小项目,里面有多线程的东东,在调试的时候 总是遇到 Windows has triggered a breakpoint in Linkage.exe 的错误。现在将这个问题和大家分享一下。
前提是这样的:
我要从数据库里面查找设备,然后找了一组设备之后,就要循环打开每一个的连接:
for (int i=0;i<records;i++) //records代表记录集条数
{
CString strCameraID;
strCameraID=CString(Anita::UTF8Tostring((char*)LResult.rows[i][0].c_str()).c_str());
TDev* p = new TDev; //TDev 是我的设备结构体
strcpy_s(p->id, Anita::UTF8Tostring((char*)LResult.rows[i][0].c_str()).c_str());
p->StartThread();
}
bool StartThread()
{
m_bStart = true;
m_pWorkerThread = AfxBeginThread(TDev::ProcessThreadProc, (void*)this,
THREAD_PRIORITY_NORMAL);
if(!m_pWorkerThread)
return false;
return true;
}
线程函数如下:
static UINT ProcessThreadProc(LPVOID pParam)
{
TDev* pThis = reinterpret_cast<TDev*>(pParam);
::OleInitialize(NULL);
while(pThis->m_bStart)
{
pThis->Work();
Sleep(30);
}
::CoUninitialize();
TRACE("EXIT THREAD");
return 0xdead;
}
按理说,这样是没有什么问题的,先查找设备集合,然后一个一个地开启线程打开设备连接。
可是在调试的时候,时不时地弹出一个错误:
注意不是每回都弹出这个问题,是时不时地弹出!
开始的时候我也一头雾水,还以为是别的什么库出了问题,找老大去说,他也随便说了说。于是我还得自己找不是.
后来我经过测试发现,一开始不弹出这个heap corruption 的情况下,系统运行的都好好的,所以问题很有可能就出在最开始了,是不是开启线程的时候就发生冲突了呢?
最后,我终于有了些发现,我那个线程函数那里找到了这句:
pThis->Work();
Sleep(30);
这个
Sleep(30);很重要啊,它给了我灵感..
线程的开启需要申请地址等等,我的数据集合那边的那个循环是不等待的(理论上)啊,这样一来第一个还没开始运行,第二个又开始了,假如后面的线程来申请地址或开始work的时候,前面的正好也在处理内存,这样不就发生冲突了嘛?
于是我就在我的那个数据集循环那里也来一个Sleep(),果然,这个问题就再也没有弹出过。
至于此处应该Sleep()多久,我就写了30毫秒,最好预留一些时间给CPU处理吧,30毫秒我想奔三也应该够了吧。。
修改的代码:
for (int i=0;i<records;i++) //records代表记录集条数
{
CString strCameraID;
strCameraID=CString(Anita::UTF8Tostring((char*)LResult.rows[i][0].c_str()).c_str());
TDev* p = new TDev; //TDev 是我的设备结构体
strcpy_s(p->id, Anita::UTF8Tostring((char*)LResult.rows[i][0].c_str()).c_str());
p->StartThread();
Sleep(30);//开启线程需要时间, 30毫秒 给 CPU,奔三也应该够了吧?!
}
经过测试,我的问题解决了。至于文中的原理是不是完全正确,希望大家多提意见..