VC 线程通信:线程读取列表数据出错!
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);
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);