读书人

VC 线程通信:线程读取列表数据出错!

发布时间: 2012-05-12 15:39:31 作者: rapoo

VC 线程通信:线程读取列表数据出错! 请教高手
VC 线程通信时,从串口线程读取数据后,传给主线程后,写到一个列表里,然后再用一个线程一直不停的读列表中的数据,一直取的数据错误,请教高手指点

SPackage_Info
{
int package_len;
CString src_data;
}
typedef std::list<SPackage_Info *> Package_InfoList;
Package_InfoList m_packList;

串口线程收到数据后通过:PostMessage()
发送给主线程接收函数:将数据写到数据列表里

LRESULT CTP::OnCommRXCharMessage(WPARAM wparam, LPARAM lparam)
{
SPackage_Info package;

unsigned long len = (DWORD)lparam;
BYTE *tmpStr = reinterpret_cast<BYTE*>(wparam);
if((tmpStr == NULL) || (len<=0)||(len >2500))
return NULL;

//EnterCriticalSection(&m_AnalyzeCommunicationSync);
package.package_len = len ;
package.src_data = tmpStr;
m_packList.push_back(&package);
//LeaveCriticalSection(&m_AnalyzeCommunicationSync);

return NULL;
}

然后单独开一个线程去读前面这个存数据列表,每读一条数据就调用解析函数去解析数据:

UINT CTP::AnalyzeThread(LPVOID pParam)
{
CTP *dlg = (CTP*)pParam;

MSG msg;
while( 1 )
{
//系统消息
while( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE))
::DispatchMessage(&msg);

//收到退出事件消息,结束线程
if(WAIT_OBJECT_0 == WaitForSingleObject(dlg->m_hAnalyzeEvent, 0))
{
return 0;
}
if( !dlg->m_packList.empty() )//m_packList队列非空
{
EnterCriticalSection(&dlg->m_AnalyzeCommunicationSync);
//把前面设置时保存到队列里的值取出更新界面
Package_InfoList::iterator itNext, it = dlg->m_packList.begin();
Package_InfoList::iterator itEnd = dlg->m_packList.end();
while(it != itEnd)
{
itNext = it;
itNext ++;
SPackage_Info *infopackage = (*it);

dlg->Decode_Data(infopackage);//Decode_Data(len, str);
dlg->m_packList.erase(it);//把列表中的某个节点取出后,删掉该节点

it = itNext;
}
LeaveCriticalSection(&dlg->m_AnalyzeCommunicationSync);
}
}

return 0;
}

解析函数:
int CTP::Decode_Data(PSPackage_Info &_package)
{
unsigned long len = _package->package_len;//_len;
BYTE tmpbyte[1000] = "";
memcpy(tmpbyte, _package->src_data.GetBuffer(), _package->src_data.GetLength());
BYTE *tmpStr = tmpbyte;/

。。。。

}



[解决办法]
直接把数据放在主线程的成员对象,链表中,然后线程去读取,不要在其他线程中访问UI对象
[解决办法]
你分别调试一下看看读数、传数、填表和读表每一步是不是都能正确执行
再有就是多线程操作要注意线程同步
否则会依法访问冲突
[解决办法]
这样:
typedef std::list<SPackage_Info > Package_InfoList;
m_packList.push_back(package);

或者

typedef std::list<SPackage_Info *> Package_InfoList;
package=new SPackage_Info;
m_packList.push_back(&package);

原因:
list参数用指针的话,m_packList.push_back(&package);时package是临时变量,每次存到list的指针都是无效的。
[解决办法]
上面有个地方错了:
typedef std::list<SPackage_Info *> Package_InfoList;
SPackage_Info *package=new SPackage_Info;
m_packList.push_back(package);
[解决办法]
你new完没有delete当然会泄露啊
要设置合理的释放机制
[解决办法]
dlg->m_packList.erase(it);//dlg->m_packList.pop_front();
delete(infopackage);


[解决办法]
线程中刷新界面不要用UpdateData就没事。
用完当前节点后把节点从list erase,然后delete节点对应的指针就可以了
[解决办法]

探讨

前面刚才说的不对,在写list之前复制时,就变的不对了

package->package_len = len ;
package->src_data = tmpStr;//

BYTE *char1 = (BYTE*)package->src_data.GetBuffer();
for(unsigned int i=0; i<len; i++)
{
str……

读书人网 >VC/MFC

热点推荐