[size=11px]现在在做一个串口的项目
发现一个奇怪的现象,当打开读串口线程后,发数据总是会导致主程序挂掉。当不打开读串口线程时,发数据一切正常。后来我去掉了线程中的WaitCommEvent(HCom,&dwEventMask,NULL); 写串口正常了,是不是WaitCommEvent一直在占用串口资源导致写串口有问题?该如何解决,谢谢了!读串口的线程如下:
DWORD dwBytesWritten;
DWORD dwEventMask=0; //发生的事件;
DWORD dwLength=0;
char Byte;
int len;
SetCommMask (HCom, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD );
PostMessage((HWND)lpData,WM_SHOW,0,0);
while(1){
len = 0;
// 等待监视的事件发生
PurgeComm(HCom, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
WaitCommEvent(HCom,&dwEventMask,NULL);
SetCommMask (HCom, EV_RXCHAR | EV_CTS | EV_DSR );
if ((dwEventMask &EV_RXCHAR)==EV_RXCHAR)
{
///开始读取循环
do
{
// Read the data from the serial port.
ReadFile (HCom,
&Byte,
1,
&dwLength,
0
);
// Display the data read.
if (dwLength == 1)
{
buf[len] = Byte;
buf[len+1] = 0;
len++;
}
}
while (dwLength == 1);
// buf[dwLength+1]='\0';
PostMessage((HWND)lpData,WM_SHOW,0,0);
写串口就是用WriteFile(HCom,send,i,&dwBytesWritten,NULL); 函数。[/size]
发现一个奇怪的现象,当打开读串口线程后,发数据总是会导致主程序挂掉。当不打开读串口线程时,发数据一切正常。后来我去掉了线程中的WaitCommEvent(HCom,&dwEventMask,NULL); 写串口正常了,是不是WaitCommEvent一直在占用串口资源导致写串口有问题?该如何解决,谢谢了!读串口的线程如下:
DWORD dwBytesWritten;
DWORD dwEventMask=0; //发生的事件;
DWORD dwLength=0;
char Byte;
int len;
SetCommMask (HCom, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD );
PostMessage((HWND)lpData,WM_SHOW,0,0);
while(1){
len = 0;
// 等待监视的事件发生
PurgeComm(HCom, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
WaitCommEvent(HCom,&dwEventMask,NULL);
SetCommMask (HCom, EV_RXCHAR | EV_CTS | EV_DSR );
if ((dwEventMask &EV_RXCHAR)==EV_RXCHAR)
{
///开始读取循环
do
{
// Read the data from the serial port.
ReadFile (HCom,
&Byte,
1,
&dwLength,
0
);
// Display the data read.
if (dwLength == 1)
{
buf[len] = Byte;
buf[len+1] = 0;
len++;
}
}
while (dwLength == 1);
// buf[dwLength+1]='\0';
PostMessage((HWND)lpData,WM_SHOW,0,0);
写串口就是用WriteFile(HCom,send,i,&dwBytesWritten,NULL); 函数。[/size]
解决方案 »
- MsgWaitForMultipleObjects和WaitForMutipleObjects到底有什么区别?
- 一个关于同步软件开发实现的问题
- 请问2000安装盘自带的工具包(support/tools)如何使用?直接安装就可以了吗?
- 请问,我在dll中声明的变量,如何在exe文件中使用,现在它说我没声明!
- 想请高手给我一点意见!
- withdll.exe 中的 0x7c94a5fd (ntdll.dll) 处有未经处理的异常
- firefox不调用我的plugin???
- 请高手来帮我看看这个BoundChecker查出来的问题
- 教教我
- 游戏编程将走向何方?大家提些看法。
- 请问如何在VC中实现将一张BMP图片以二进制或八进制读入(请看具体说明)?
- 规则配置文件应该用什么格式的语言写比较好,是文本文件呢,还是XML?
楼主都没有看明白 WaitCommEvent 函数的用法就开始编码了!阻塞方式下,WaitCommEvent 可能会阻塞线程。
不要整天急,急是不可能写出好程序的!
{
CManageCom4* apThis = (CManageCom4*) pvParam ;
bool abContinue = true;
DWORD dwEventMask=0;
OVERLAPPED ov;
memset(&ov,0,sizeof(ov));
ov.hEvent = CreateEvent( 0,true,0,0);
HANDLE arHandles[2];
arHandles[0] = apThis->m_hThreadTerm; DWORD dwWait;
BOOL bRead=FALSE;
SetEvent(apThis->m_hThreadStarted);
while ( abContinue )
{
BOOL abRet = ::WaitCommEvent(apThis->m_hComm,&dwEventMask, &ov) ;
if ( !abRet )
{
ASSERT( GetLastError () == ERROR_IO_PENDING);
}
arHandles[1] = ov.hEvent ;
dwWait = WaitForMultipleObjects (2,arHandles,FALSE,INFINITE);
switch ( dwWait )
{
case WAIT_OBJECT_0:
{
_endthreadex(1);
}
break;
case WAIT_OBJECT_0 + 1:
{
DWORD dwMask;
if (GetCommMask(apThis->m_hComm,&dwMask) )
{
if ( dwMask == EV_TXEMPTY )
{
AfxMessageBox("Data sent");
ResetEvent ( ov.hEvent );
continue;
}
}
int iAccum = 0;
apThis->m_theSerialBuffer.LockBuffer();
try
{
std::string szDebug;
BOOL abRet = false;
DWORD dwBytesRead = 0;
OVERLAPPED ovRead;
memset(&ovRead,0,sizeof(ovRead));
ovRead.hEvent = CreateEvent( 0,true,0,0);
do
{
ResetEvent( ovRead.hEvent );
char *szTmp=new char [apThis->m_nReadCount];
int iSize = apThis->m_nReadCount;
memset(szTmp,0,iSize);
abRet = ::ReadFile(apThis->m_hComm,szTmp,iSize,&dwBytesRead,&ovRead);
if (!abRet )
{
abContinue = FALSE;
break;
}
if ( dwBytesRead > 0 )
{
apThis->m_theSerialBuffer.AddData ( szTmp,dwBytesRead );
iAccum += dwBytesRead;
bRead=TRUE;
::Sleep(100);
}
delete szTmp;
}while (dwBytesRead);
CloseHandle(ovRead.hEvent );
}
catch(...)
{
ASSERT(0);
}
if (apThis->GetCurrentState() != SS_Started )
{
iAccum = 0;
apThis->m_theSerialBuffer.Flush ();
}
apThis->m_theSerialBuffer.UnLockBuffer();
if(apThis->m_hParent&&bRead)
::SendMessage(apThis->m_hParent,WM_RECEIVE_DATA,apThis->m_nPort,NULL);
ATLTRACE6(_T("RCSerial: Q Unlocked:"));
if ( iAccum > 0 )
{
ATLTRACE6(_T("CManageCom4(worker thread): SetDataReadEvent() len:{%d} data:{%s}"),iAccum,(apThis->m_theSerialBuffer.GetData()).c_str () );
apThis->SetDataReadEvent();
}
ResetEvent ( ov.hEvent );
}
break;
}
}
return 0;
}
DWORD TheardEvent(LPVOID pParam)
{
OS = {0};
BOOL bCommState = TRUE;
DWORD deEvtMask, dwRes;
DWORD dwTimeOutValue, dwErrors;
COMSTAT ComStat; OS.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
while (bCommState)
{
WaitCommEvent(hCom, &deEvtMask, &OS);
dwRes = WaitForSingleObject(OS.hEvent, &dwTimeOutValue);
if(WAIT_OBJECT_0 == dwRes) //监视事件发生
{
if(EV_RXCHAR == deEvtMask) //有数据到达
{
ClearCommError(hCom, &dwErrors, &ComStat);
if(0 != ComStat.cbInQue) //数据长度不为0
{
Read()... //读取
}
}
} }
return 0;
}