我正在使用 Windows 功能开发串行通信软件。在此 CSerialCommhelper 是处理所有串行通信功能的类,而 CphysicalLayer 是利用该类的类。
class CSerialCommHelper :
public CCommAgent
{
HANDLE m_pPortHandle; //Handle to the COM port
HANDLE m_hReadThread; //Handle to the Read thread
HANDLE m_hPortMutex; //Handle to Port Mutex
std::wstring m_strPortName; //Portname
COMMTIMEOUTS m_CommTimeouts; //Communication Timeout Structure
_DCB dcb; //Device Control Block
DWORD m_dwThreadID; //Thread ID
public:
CSerialCommHelper(CPhysicalLayer *);
virtual HRESULT Open();
virtual HRESULT ConfigPort();
static void * ReadThread(void *);
virtual HRESULT Write(const unsigned char *,DWORD);
virtual HRESULT Close();
//virtual HRESULT Flush(DWORD dwFlag = PURGE_TXCLEAR | PURGE_RXCLEAR);
wstring StringToWstring(const string &);
~CSerialCommHelper(void);
};
CommAgent 包含一个 CphysicalLayer 指针,用于在接收到数据时通知物理层。
HRESULT CSerialCommHelper::Write(const unsigned char *pucDataToWrite,DWORD ulLength)
{
unsigned long bytesWritten=0, ij = 0;
WaitForSingleObject(m_hPortMutex,INFINITE);
if(WriteFile(m_pPortHandle,pucDataToWrite,ulLength,&bytesWritten,NULL))
{
if(!ReleaseMutex(m_hPortMutex))
{
DWORD err=GetLastError();
// Mutex released succesfully..
}
}
if (bytesWritten != ulLength)
return E_FAIL;
return S_OK;
}
void * CSerialCommHelper::ReadThread(void * pObj)
{
CSerialCommHelper *pCSerialCommHelper =(CSerialCommHelper *)pObj;
DWORD dwBytesTransferred = 0;
unsigned char byte = 0;
while (pCSerialCommHelper->m_pPortHandle != INVALID_HANDLE_VALUE)
{
pCSerialCommHelper->m_strBuffer.clear();
pCSerialCommHelper->m_usBufSize=0;
WaitForSingleObject(pCSerialCommHelper->m_hPortMutex,INFINITE);
do
{
dwBytesTransferred = 0;
ReadFile (pCSerialCommHelper->m_pPortHandle, &byte, 1, &dwBytesTransferred, 0);
if (dwBytesTransferred == 1)
{
pCSerialCommHelper->m_strBuffer.push_back(byte);
pCSerialCommHelper->m_usBufSize++;
continue;
}
}
while (dwBytesTransferred == 1);
if(pCSerialCommHelper->m_usBufSize!=0)
{
CProtocolPacket *pCProtocolPacket = new CProtocolPacket(0,2048);
pCProtocolPacket->AddBody(pCSerialCommHelper->m_usBufSize,(unsigned char*)pCSerialCommHelper->m_strBuffer.c_str());
pCSerialCommHelper->m_pCPhysicalLayer->Data_ind(pCProtocolPacket);
delete pCProtocolPacket;
}
ReleaseMutex(pCSerialCommHelper->m_hPortMutex);
Sleep(2);
}
ExitThread(0);
return 0;
}
这就是我创建文件和互斥锁的方式
m_pPortHandle = CreateFile(m_strPortName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING,NULL, NULL );
if (m_pPortHandle == INVALID_HANDLE_VALUE)
{
return E_HANDLE;
//throw failure
}
m_hPortMutex = CreateMutex(NULL,TRUE,L"MY_MUTEX");
if( m_hReadThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ReadThread,(LPVOID)this,0,&m_dwThreadID))
{
}
else
{
return E_FAIL;
}
return S_OK;
但是在将字符串写入端口后,写入函数成功释放互斥锁,但读取线程仍在等待。