[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]

解决方案 »

  1.   


    楼主都没有看明白 WaitCommEvent 函数的用法就开始编码了!阻塞方式下,WaitCommEvent 可能会阻塞线程。
    不要整天急,急是不可能写出好程序的!
      

  2.   

    ThreadFn(void*pvParam)
    {
    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;
    }
      

  3.   

    //以事件驱动的读线程
    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;
    }
      

  4.   

    网上有这样的例子你好好找找。cserial你的代码是否考的不正确