创建一个线程来接收串口数据,为什么正常收一段时间后(10多分钟)就不再收任何东西了?

时间:2023-01-06 16:59:26
线程好象在wait函数处锁死,为什么?
void __fastcall TReadThread::Execute(void)
   {
   char szInputBuffer[INPUTBUFFERSIZE];
   DWORD nNumberOfBytesRead;
   DWORD fdwEvtMask;
   DWORD dwHandleSignaled;
   HANDLE HandlesToWaitFor[2];
   OVERLAPPED m_OverlappedRead;
   FillMemory((PVOID)&m_OverlappedRead,sizeof(m_OverlappedRead),0);
   m_OverlappedRead.hEvent=CreateEvent(NULL,true,false,NULL);
   HandlesToWaitFor[0]=hCloseEvent;
   HandlesToWaitFor[1]=m_OverlappedRead.hEvent;
   is_Reading=false;
   while(1)
       {
       if (!is_Reading)
         if (!ReadFile(hCommFile,szInputBuffer,INPUTBUFFERSIZE,&nNumberOfBytesRead,&m_OverlappedRead))
             if (GetLastError()==ERROR_IO_PENDING) is_Reading=true;
           else
             HandleReadData(szInputBuffer,nNumberOfBytesRead);
      if (is_Reading)
        {
         dwHandleSignaled=WaitForMultipleObjects(2,HandlesToWaitFor,false,INFINITE);
         switch(dwHandleSignaled)
          {
          case WAIT_OBJECT_0:
                 goto EndReadThread;
          case WAIT_OBJECT_0+1:
                  if (GetOverlappedResult(hCommFile,&m_OverlappedRead,&nNumberOfBytesRead,false))
                       HandleReadData(szInputBuffer,nNumberOfBytesRead);
                  is_Reading=false;
                  break;
          case WAIT_FAILED:
                  goto EndReadThread;
          }
        }
        }
EndReadThread:
        PurgeComm(hCommFile,PURGE_RXABORT|PURGE_RXCLEAR);
        CloseHandle(m_OverlappedRead.hEvent);
  }

19 个解决方案

#1


你有没有设置串口的超时
用函数SetCommTimeouts()

#2


只用了ReadIntervalTimeout=100,与这个有关系吗?

#3


mark

#4


??????????????????

#5


Is_Reading只在一个地方设置为FALSE,如何碰不到这个事件,在什么地方将其设为FALSE?Is_Reading总是TRUE,将不再读新的数据。

#6


学习

#7


为什么会碰不到这个事件呢,如果有未完成的I/O操作,则将is_Reading赋为true,然后等待读操作完成,如果检测到事件,则将is_Reading赋为false,开始下一次读操作,这样不对吗?

#8


我检测了线程的运行情况,线程好像是在wait函数处陷入了无限的等待状态,为什么会这样呢?盼复!!!急

#9


学习

#10


bool __fastcall TReadThread::HandleReadData(char *lpszInputBuffer,DWORD dwSizeofBuffer)
    {
    char *lpszPostedBytes;
    if (dwSizeofBuffer)
       {
       lpszPostedBytes=(char*)LocalAlloc(LPTR,dwSizeofBuffer+1);
       if (lpszPostedBytes==NULL)
         {
         return false;
         }
         Move(lpszInputBuffer,lpszPostedBytes,dwSizeofBuffer);
         lpszPostedBytes[dwSizeofBuffer]=0;
         return ReceiveData(lpszPostedBytes,dwSizeofBuffer);
       } 
   return false;
   }
//------------------------------------------------------------------
bool __fastcall TReadThread::ReceiveData(char *lpNewString,DWORD dwSizeofNewString)
   {
   if (!PostMessage(hWindow,WM_GOTCOMMDATA,(WPARAM)dwSizeofNewString,(LPARAM)lpNewString))
        return false; 

   return true;
   }
//------------------------------------------------------------------

#11


你在ENDXXX的后面加上IsReading = false; 试试看

既然用的是C,最好不要用GOTO语句,结构混乱。

#12


如果到了EndXXX,线程就结束了阿。

#13


postmessage是异步函数,不能从返回值中得到是否已被处理,用sendmessage是同步的,除非发送目的方已处理,否则等待,你可以用他的一个变体,设定等待的时间,超时返回

#14


空了再来看。不过老兄,我名字是com235,就是串口的“收、发、地”三根线,哈哈哈,在这个上面混过很久饭吃。

降龙一八掌:
           用*MOXA公司的卡带的库吧,可以在没用它的硬件下用(就是说是个通用的),我曾经从串口每天收接近1个G的数据,那个软件还是7*24小时工作,非常稳定,反正在交工前的几个月就从来没宕机过。是个绝对工业级的软件。哈哈哈哈哈,如何谢我。

#15


请问哪里有下载,com235老兄,急!不胜感激!!!

#16


三天了,各位大侠救命阿!!!!

#17


我线程是这样做的,你看一下吧。
完整的东西在:http://www.csdn.net/expert/topic/701/701200.xml?temp=.7650415
void __fastcall TSTCommThread::Execute()
{
    DWORD      dwCommEvent;
    OVERLAPPED osStatus = {0};
    if (!SetCommMask(hComm, dwStoredFlags))
        return;
    osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (osStatus.hEvent == NULL)      // error creating event; abort
        return;
    while(!Terminated) {
        if (!WaitCommEvent(hComm, &dwCommEvent, &osStatus)){
            if (GetLastError() == ERROR_IO_PENDING);
            // fWaitingOnStat= TRUE;
            else{ // error in WaitCommEvent; abort
                ShowMessage("error in WaitCommEvent");
                break;
            }
         }
         else{  // Deal with status event as appropriate.
            if((dwCommEvent&EV_RXCHAR)||(dwCommEvent&EV_TXEMPTY)||(dwCommEvent&EV_ERR))
                if(FNotify)
                    FNotify(dwCommEvent);//调用处理函数
         }
    }
    CloseHandle(osStatus.hEvent);
}
//---------------------------------------------------------------------------

#18


不好意思,对不起,实在是太忙,
你去 http://www.moxa.com 看看,应该有down。关键是他的help非常好,每个函数都有有VB Deilph VC C 的例子,就一二句的那样,你看看,2天搞定应该没问题。

#19


虽然没有解决问题,但还是谢谢各位的热心帮助!
to com235:我去www.moxa.com看了,好象是注册用户才有得下。

#1


你有没有设置串口的超时
用函数SetCommTimeouts()

#2


只用了ReadIntervalTimeout=100,与这个有关系吗?

#3


mark

#4


??????????????????

#5


Is_Reading只在一个地方设置为FALSE,如何碰不到这个事件,在什么地方将其设为FALSE?Is_Reading总是TRUE,将不再读新的数据。

#6


学习

#7


为什么会碰不到这个事件呢,如果有未完成的I/O操作,则将is_Reading赋为true,然后等待读操作完成,如果检测到事件,则将is_Reading赋为false,开始下一次读操作,这样不对吗?

#8


我检测了线程的运行情况,线程好像是在wait函数处陷入了无限的等待状态,为什么会这样呢?盼复!!!急

#9


学习

#10


bool __fastcall TReadThread::HandleReadData(char *lpszInputBuffer,DWORD dwSizeofBuffer)
    {
    char *lpszPostedBytes;
    if (dwSizeofBuffer)
       {
       lpszPostedBytes=(char*)LocalAlloc(LPTR,dwSizeofBuffer+1);
       if (lpszPostedBytes==NULL)
         {
         return false;
         }
         Move(lpszInputBuffer,lpszPostedBytes,dwSizeofBuffer);
         lpszPostedBytes[dwSizeofBuffer]=0;
         return ReceiveData(lpszPostedBytes,dwSizeofBuffer);
       } 
   return false;
   }
//------------------------------------------------------------------
bool __fastcall TReadThread::ReceiveData(char *lpNewString,DWORD dwSizeofNewString)
   {
   if (!PostMessage(hWindow,WM_GOTCOMMDATA,(WPARAM)dwSizeofNewString,(LPARAM)lpNewString))
        return false; 

   return true;
   }
//------------------------------------------------------------------

#11


你在ENDXXX的后面加上IsReading = false; 试试看

既然用的是C,最好不要用GOTO语句,结构混乱。

#12


如果到了EndXXX,线程就结束了阿。

#13


postmessage是异步函数,不能从返回值中得到是否已被处理,用sendmessage是同步的,除非发送目的方已处理,否则等待,你可以用他的一个变体,设定等待的时间,超时返回

#14


空了再来看。不过老兄,我名字是com235,就是串口的“收、发、地”三根线,哈哈哈,在这个上面混过很久饭吃。

降龙一八掌:
           用*MOXA公司的卡带的库吧,可以在没用它的硬件下用(就是说是个通用的),我曾经从串口每天收接近1个G的数据,那个软件还是7*24小时工作,非常稳定,反正在交工前的几个月就从来没宕机过。是个绝对工业级的软件。哈哈哈哈哈,如何谢我。

#15


请问哪里有下载,com235老兄,急!不胜感激!!!

#16


三天了,各位大侠救命阿!!!!

#17


我线程是这样做的,你看一下吧。
完整的东西在:http://www.csdn.net/expert/topic/701/701200.xml?temp=.7650415
void __fastcall TSTCommThread::Execute()
{
    DWORD      dwCommEvent;
    OVERLAPPED osStatus = {0};
    if (!SetCommMask(hComm, dwStoredFlags))
        return;
    osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (osStatus.hEvent == NULL)      // error creating event; abort
        return;
    while(!Terminated) {
        if (!WaitCommEvent(hComm, &dwCommEvent, &osStatus)){
            if (GetLastError() == ERROR_IO_PENDING);
            // fWaitingOnStat= TRUE;
            else{ // error in WaitCommEvent; abort
                ShowMessage("error in WaitCommEvent");
                break;
            }
         }
         else{  // Deal with status event as appropriate.
            if((dwCommEvent&EV_RXCHAR)||(dwCommEvent&EV_TXEMPTY)||(dwCommEvent&EV_ERR))
                if(FNotify)
                    FNotify(dwCommEvent);//调用处理函数
         }
    }
    CloseHandle(osStatus.hEvent);
}
//---------------------------------------------------------------------------

#18


不好意思,对不起,实在是太忙,
你去 http://www.moxa.com 看看,应该有down。关键是他的help非常好,每个函数都有有VB Deilph VC C 的例子,就一二句的那样,你看看,2天搞定应该没问题。

#19


虽然没有解决问题,但还是谢谢各位的热心帮助!
to com235:我去www.moxa.com看了,好象是注册用户才有得下。

#20