龚建伟老师编写的串口类CSerialPort问题--测试发现串口总是关闭不掉
各位高手,我在使用龚建伟老师编写的串口类CSerialPort时发现书中的原码存在无法关闭串口的问题,请赐教!
(1)龚老师在InitPort中使用CreateFile函数对串口进行了初始化,并且使用CreateEvent创建了3个事件,简单如下:
// create events
if (m_ov.hEvent != NULL)
ResetEvent(m_ov.hEvent);
else
m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_hWriteEvent != NULL)
ResetEvent(m_hWriteEvent);
else
m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_hShutdownEvent != NULL)
ResetEvent(m_hShutdownEvent);
else
m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hEventArray[0] = m_hShutdownEvent;
m_hEventArray[1] = m_ov.hEvent;
m_hEventArray[2] = m_hWriteEvent;
(2)创建一个监听线程,在监听线程中完成串口的读、写、关闭操作。
UINT CSerialPort::CommThread(LPVOID pParam)
{
CSerialPort *port = (CSerialPort*)pParam;
port->m_bThreadAlive = TRUE;
DWORD BytesTransfered = 0;
DWORD Event = 0;
DWORD CommEvent = 0;
DWORD dwError = 0;
COMSTAT comstat;
BOOL bResult = TRUE;
if (port->m_hComm)
PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
for (;;)
{
bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);
if (!bResult)
{
switch (dwError = GetLastError())
{
case ERROR_IO_PENDING:
break;
case 87:
break;
default:
port->ProcessErrorMessage("WaitCommEvent()");
break;
}
}
else
{
bResult = ClearCommError(port->m_hComm, &dwError, &comstat);
if (comstat.cbInQue == 0)
continue;
}
Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE);
switch (Event)
{
case 0:
CloseHandle(port->m_hComm);
port->m_hComm=NULL;
port->m_bThreadAlive = FALSE;
AfxEndThread(100);
break;
case 1:
GetCommMask(port->m_hComm, &CommEvent);
if (CommEvent & EV_RXCHAR)
ReceiveChar(port, comstat);
break;
case 2:
WriteChar(port);
break;
}
}
return 0;
}
(3) 按照我个人的理解,在监听线程中,当线程完成一次读或写或关闭操作后就会被
Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE)阻塞,然后通过SetEvent()来将线程运行起来执行相关的操作。
(4) 我测试发现,读写的时候是可以正常工作的,但是读写完成之后,用SetEvent(hShutdownEvent)发送关闭串口事件后,线程总是
没有响应,好像线程始终处于阻塞状态,这样串口始终无法关闭,主要是线程没有被关闭。
他的关闭函数是这样的:
void CSerialPort::ClosePort()
{
SetEvent(m_hShutdownEvent);
}
CSerialPort::~CSerialPort()
{
do
{
SetEvent(m_hShutdownEvent);
} while (m_bThreadAlive);
if (m_hComm != NULL)
{
CloseHandle(m_hComm);
m_hComm = NULL;
}
if(m_hShutdownEvent!=NULL)
CloseHandle( m_hShutdownEvent);
if(m_ov.hEvent!=NULL)
CloseHandle( m_ov.hEvent );
if(m_hWriteEvent!=NULL)
CloseHandle( m_hWriteEvent );
TRACE("Thread ended\n");
delete [] m_szWriteBuffer;
}
请高手们指点迷津呀!!