龚建伟老师编写的串口类CSerialPort问题--测试发现串口总是关闭不掉

zhou_cocoo 2011-12-17 12:42:17
各位高手,我在使用龚建伟老师编写的串口类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;
}
请高手们指点迷津呀!!
...全文
608 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
steven96016 2014-07-20
  • 打赏
  • 举报
回复
我在close代码中加入以下程序,问题解决。 StopMonitoring(); CloseHandle(m_hComm); m_hComm = NULL; 问题就解决了
zhouzhipen 2011-12-20
  • 打赏
  • 举报
回复
这不是什么代码问题,如果你用的是USB转的串口、虚拟串之类的东西,大部分是因为这些东西的驱动没有写好,造成上层应用的死锁,这种问题遇到了无数次了。最后办法就只有用好一点厂商的USB串口,或直接用串口卡。谁叫这年头电脑上都不配串口了。
liquanhai 2011-12-20
  • 打赏
  • 举报
回复
看看我总结的,怎么解决串口类CserialPort关闭死锁问题。其他类似的问题,可以给我留言!
用户 昵称 2011-12-20
  • 打赏
  • 举报
回复
还有个老外的CSerialPort
http://www.codeproject.com/KB/system/cserialport.aspx
最帅的小猪 2011-12-17
  • 打赏
  • 举报
回复
龚建伟写的那个CserialPort类操作一个串口时打开和关闭是正常的,如果操作多个串口就会有问题,你可以改写下其中的ClosePort(),找下网上有相关资料!
zhou_cocoo 2011-12-17
  • 打赏
  • 举报
回复
楼上的您好,
请问,你还有没有保存改过后的类的源码,能否给我共享一下,非常感谢!!
woshixiaocaomei 2011-12-17
  • 打赏
  • 举报
回复
我以前也碰到过这样的问题,串口一直释放不掉。后来我用了别人改过的CSerialPort类,好了

2,644

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧