如在主线程中定义了一个对象数据.CArray<CXXObject,CXXObject&> m_objXXGroups;(CXXObject代表一个串口的数据对象)(CXXObject是线程无关的,即它自己保护了多个线程同时访问(读写)它的变量.)现有一个子线程是不断的向m_objXXGroups中的元素写数据。另有多个线程.(即为m_objXXGroups中的每个元素创建了一个线程(每个串口一个线程),不停的取出数据来发送..),它会把通信的结果通过PostMessage(主线程的窗口句柄,WM_XXX,L,P)报告它,让它在主界面中显示结果。<发送线程>
请问:
1.需要保护m_objXXGroups变量吗?
2.关于发送线程:
UINT SendThreadProc(LPVOID lpParameter).
发送线程组是对这个线程函数多次调用AfxBeginThread产生的。
问:在SendThreadProc()中定义变量。如long lLength.进行保护吗?因为它有多个线程实例.
我的程序有时会死掉,不知为什么.
请问:
1.需要保护m_objXXGroups变量吗?
2.关于发送线程:
UINT SendThreadProc(LPVOID lpParameter).
发送线程组是对这个线程函数多次调用AfxBeginThread产生的。
问:在SendThreadProc()中定义变量。如long lLength.进行保护吗?因为它有多个线程实例.
我的程序有时会死掉,不知为什么.
解决方案 »
- 用VC做了一个人事管理系统,数据库连接问题
- 对MFC的默认打印机制有点小疑惑
- 转让《深入浅出MFC》2e,《C++ PRIMER》3e,WIN32多线程程序设计
- VS.NET2003 有没有语法查错功能?
- 寻求能在Outlook Express 下实现内嵌工具栏按钮的源代码---要求自己做的,有说明文档,报酬面议
- 一个简单的汇编问题!
- 誰能幫我選款精英主板,謝謝。。
- 哪位先生知道Windows CE Toolkit for VC6下载网址或有现成的程序包?
- 用MFC如何实现像记事本中的自动换行切换功能?
- BYTE[16]转化成CTime
- 请教:VC6.0,将头文件加入工程中编译,和不加入工程中编译有何区别?好像都可以编译过
- ~~~~~~~~~~高手请进~~~~~~~~~~Windows下CTRL+X, CTRL+C, CTRL+V是调用哪些系统API~~~~~~~~~
但我仔细检查了程序。不会出现死锁。但好象还是死锁了。即程序死掉了.(而且在DEBUG模式下调试.)
{
AfxOleInit(); CStationLedApp *pApp = (CStationLedApp*) AfxGetApp();
CStationLedView *pView = (CStationLedView*)lpParameter; ASSERT(pView != NULL && pApp != NULL);
POSITION pos = pView->m_lstWelInfo.GetHeadPosition();
pView->m_cs.Lock();
int nComCount = pView->m_ComGroups.GetSize();
int nMaxLedCount = 0;
for (int i=0;i<pView->m_ComGroups.GetSize();i++)
{
int nTemp = pView->m_ComGroups[i].m_LedGroups.GetSize();
if (nMaxLedCount < nTemp)
nMaxLedCount = nTemp;
}
pView->m_cs.Unlock();
CLedDotData LedDotData;
while (1)
{
if (WAIT_OBJECT_0 == WaitForSingleObject(pView->m_hEvtDatabase,0))
goto __DO_EXIT; if (!pApp->IsDataBaseOpen())
pApp->OpenDatabase(pApp->g_szDatabasePathName);
if (WAIT_OBJECT_0 == WaitForSingleObject(pView->m_hEvtDatabase,0))
goto __DO_EXIT; if (pApp->IsDataBaseOpen())
{
TRACE("Database Thread\n");
for (int i=0;i<nMaxLedCount;i++)
{
for (int k=0;k<nComCount;k++)
{
pView->m_cs.Lock();
int nTempCount = pView->m_ComGroups[k].m_LedGroups.GetSize();
int nCheckID = pView->m_ComGroups[k].m_LedGroups[i].nCheckID;
pView->m_cs.Unlock();
if (nTempCount > i)
{
CArray<BUSINFO,BUSINFO&> BusInfos; LedDotData.QueryLineInfo(pApp->m_pConn,nCheckID,
pApp->g_nSendBeforTime,pApp->g_nCheckBeforTime,BusInfos);
ASSERT(BusInfos.GetSize() == 1);
if (BusInfos[0].Flag == 0 && pos != NULL)
{
BusInfos[0].Infomation = pView->m_lstWelInfo.GetNext(pos);
if (BusInfos[0].Infomation == _T(""))
BusInfos[0].Infomation = _T("热烈祝贺\\n天台车站正式开通");
if (pos)
pos = pView->m_lstWelInfo.GetHeadPosition();
}
else if (BusInfos[0].Flag == 0)
BusInfos[0].Infomation = _T("热烈祝贺\\n天台车站正式开通");
pView->m_cs.Lock();
pView->m_ComGroups[k].m_LedGroups[i].AddBusInfo(BusInfos);
pView->m_cs.Unlock();
}
if (WAIT_OBJECT_0 == WaitForSingleObject(pView->m_hEvtDatabase,0))
goto __DO_EXIT;
}
}
}
for (int k=0;k<pApp->g_nRefreshDatabaseTime;k++)
{
if (WAIT_OBJECT_0 == WaitForSingleObject(pView->m_hEvtDatabase,0))
goto __DO_EXIT;
Sleep(1000);
}
}
__DO_EXIT:
pApp->CloseDatabase();
TRACE(_T("Database Thread Exited!\n"));
return 0;
}UINT CStationLedView::SendProc(LPVOID lpParameter)
{
SendThreadParam *pParam = (SendThreadParam*)lpParameter;
HWND hWnd = pParam->hWnd;
CStationLedView *pView = (CStationLedView*)pParam->pView;
CStationLedApp *pApp = (CStationLedApp*) AfxGetApp();
ASSERT(pView != NULL && pApp != NULL && hWnd != NULL); int nComIndex = 0;
int nPort = pParam->nPort;
int i,nSize;
CString szSetting = pParam->szSetting; //////////////////////////////////////////////////////////////////////////
HANDLE hEvtTemp = ::CreateEvent(NULL,TRUE,FALSE,NULL);
//////////////////////////////////////////////////////////////////////////
CLedCom LedCom;
if (!LedCom.CreateInterface(nPort,szSetting))
goto __DO_FAILT_EXIT;
pView->m_cs.Lock();
nSize = pView->m_ComGroups.GetSize();
for (i=0;i<nSize;i++)
{
if (pView->m_ComGroups[i].nPort == pParam->nPort)
break;
}
pView->m_cs.Unlock(); nComIndex = i;
ASSERT(nComIndex<= nSize);
while (1)
{
pView->m_cs.Lock();
int nLedCount = pView->m_ComGroups[nComIndex].m_LedGroups.GetSize();
pView->m_cs.Unlock(); if (nLedCount == 0) goto __DO_EXIT;
if (WAIT_OBJECT_0 == ::WaitForSingleObject(pParam->m_hEvtCanExit,0))
goto __DO_EXIT; ::WaitForSingleObject(hEvtTemp,500); for (i=0;i<nLedCount;i++)
{
if (WAIT_OBJECT_0 == ::WaitForSingleObject(pParam->m_hEvtCanExit,0))
goto __DO_EXIT;
BUSINFO businfo;
CByteArray byData;
CLedDotData LedDotData;
CFont font;
LEDEC ret = LEDEC_ERRORSUCCESS; pView->m_cs.Lock();
BOOL bFlag = pView->m_ComGroups[nComIndex].m_LedGroups[i].GetBusInfo(businfo);
pView->m_cs.Unlock(); if (!bFlag) continue;
{
pView->m_cs.Lock();
int nAddr = pView->m_ComGroups[nComIndex].m_LedGroups[i].nAddr;
int nLedID = pView->m_ComGroups[nComIndex].m_LedGroups[i].nLedID;
int nAreaCount = pView->m_ComGroups[nComIndex].m_LedGroups[i].m_nAreaCount;
pView->m_cs.Unlock(); if (businfo.Flag == 0)
{
//.........
}
else if (businfo.Flag == 1)
{
//...
}
else if (businfo.Flag == 2)
{
//........
}
}
//Sleep(50);
}
}
__DO_EXIT:
{
//........... }
}
__DO_FAILT_EXIT:
::SetEvent(pParam->m_hEvtExited);
TRACE(_T("Com%d Thread Exited!\n"),nPort);
return 0;
}
AfxBeginThread(DataBaseProc,*****);
for (int i=0;i<nSize;i++)
{
............
AfxBeginThread(SendProc,....);
}
我的程序关于多个线程并行操作是正确的.(每个串口一个线程发送数据。一个线程从数据库准备数据。)
(我把串口线程中的发送数据注释掉,就正确了。)问题好象出在发送上:
串口发送是用mscomm32.ocx控件来操作的。
我自己写一个了发送类CLedComm,封装通讯信息.发送数据用mscomm32.ocx来实现.
在发送线程中创建发送类.(发送类创建CMSComm的实例。)
????? 由于是在每个发送线程中创建的CLedComm.因此CLedComm不存在同步问题(是吗?)
是不是在发送线程中要实现COM的MTA.(比如在一个线程中创建ADO的实例,在创建之间一定还要调用AfxOleInit一样。在发送线程中要实始COM的MTA.)
倒底应该怎样做?