RS-232-C端口实时监控软件的设计实现(3)
(三) 侦听监视线程
当成功的打开端口之后通过执行线程开启函数AfxBeginThread(COMReadThreadProc,NULL,THREAD_PRIORITY_NORMAL);开启了一个用于侦听端口的工作线程COMReadThreadProc。其具体处理过程
如下:
UINT COMReadThreadProc(LPVOID pParam)
{
……
file://设置读端口线程执行标志的标识
g_comthread.SetReadThreadKillFlag(FALSE);
while(1)
{
file://读取端口开启状态的标识
if(TRUE==g_comthread.GetCloseCOMFlag())
{
g_comthread.SetReadThreadKillFlag(TRUE);
return 0;//正常关闭
}
file://读端口操作
dwNeedRead=500;
file://从端口读取数据到缓存中
if(!ReadFile(g_hCom,buf,dwNeedRead,&dwActRead,NULL))
{
ClearCommError(g_hCom,&dwErrorMask,&comstat);
PurgeComm(g_hCom,PURGE_RXCLEAR);
continue;
}
file://读字符加入到全局缓冲
g_comreadbuf.Add(buf,dwActRead);
Sleep(1);
}
……
return 0;
}
其中用到的g_comthread和g_comreadbuf分别是线程类CCOMThread和读端口类COMReadBuf的实例对象。这两个类里都用类CCriticalSection m_Lock;实现了临界区技术,用以保持线程间的同步。CCOMReadBuf类的两个函数GetOneByte(……)、Add(……)分别用于从端口读取一个字符和向缓冲区添加读取的字符。其主要实现代码如下:
BOOL CCOMReadBuf::GetOneByte(BYTE *cb)
{
m_Lock.Lock();
if(m_nHead==m_nTail)
{
m_Lock.Unlock();
return FALSE;//空
}
*cb=m_readbuf[m_nTail];
if(m_nTail < m_nBufSize-1)
m_nTail++;
else
m_nTail=0;
m_Lock.Unlock();
return TRUE;//空
}
void CCOMReadBuf::Add(BYTE buf[],int nBytes)
{
int nt,i;
m_Lock.Lock();
for(i=0;iBR> {
nt=(m_nHead-m_nTail);
if(nt<0)
nt+=m_nBufSize;
if(nt+1==m_nBufSize)
break;//缓冲区满
m_readbuf[m_nHead]=buf[i];
if(m_nHead < m_nBufSize-1)
m_nHead++;
else
m_nHead=0;
}
m_Lock.Unlock();
}