Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Thread'ы в процессах


Автор: bel_nikita 27.10.2004, 08:51
Есть программа, в ней создаю нитку(thread). А в нем типа вечный двигатель( while (true){ tra-la-la; WaitForSingleObject; tra-la-la } ) После этого мой тред сжирает 95-98% процессорного времени. Как от этого избавлятся?

Автор: Adil' 27.10.2004, 09:07
В принципе, использование WaitForSingleObject не должно приводить к этому. Покажешь, что внутри while?

Автор: Step 27.10.2004, 09:10
во первых какая нить интерфейсная или рабочая... второй параметр у WaitForSingleObject какой

вообще код весь привиди... весь цикл

Автор: bel_nikita 27.10.2004, 10:23
у меня там com-port юзается, и я думаю проблема в WaitCommEvent

Вот вырезка с кода, но я думаю он мало чем поможет:
Код
/************************************************************************/
/* FUNCTION    : Loop()                                                 */
/* OBJECT      : cBarCode                                               */
/* PURPOSE     : thread com port process                                */
/* PARAMETERS  : none                                                   */
/* RETURN VALUE: none                                                   */
/* COMMENT     : none                                                   */
/************************************************************************/
void cBarCode::Loop()
{
 while(!_isDying)
 {
   {
     Process();
   }
 }
}

/************************************************************************/
/* FUNCTION    : Process()                                              */
/* OBJECT      : cBarCode                                               */
/* PURPOSE     : com port process                                       */
/* PARAMETERS  : none                                                   */
/* RETURN VALUE: none                                                   */
/* COMMENT     : none                                                   */
/************************************************************************/
void cBarCode::Process()
{
 DWORD dwRes = 0;
 DWORD dwOvRes = 0;
 DWORD dwCommModemStatus = 0;

    if( !fWaitingOnStat && !WaitCommEvent(m_hPort, &dwCommModemStatus, &m_evStatus) )
   {
     if(GetLastError() == ERROR_IO_PENDING)
       fWaitingOnStat = TRUE;
     else
     {
       Event(dwCommModemStatus); // read from com
     }
   }
   if (fWaitingOnStat)
   {
     dwRes = WaitForSingleObject(m_evStatus.hEvent, 500);
     if(dwRes==WAIT_OBJECT_0)
     {            
       // Event occurred.
       if (GetOverlappedResult(m_hPort, &m_evStatus, &dwOvRes, FALSE))
         Event(dwCommModemStatus); // read from com
       fWaitingOnStat = FALSE;
     }
   }
   SetCommMask (m_hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING);
   GetCommModemStatus (m_hPort, &dwCommModemStatus);

}


Автор: Step 27.10.2004, 10:34
подозреваю что это условие выполняеться очень редко
if (fWaitingOnStat)



вот это странно
if(GetLastError() == ERROR_IO_PENDING)
fWaitingOnStat = TRUE;
може false

Автор: Monomah 27.10.2004, 10:35
Поставь где-нибудь в цикле Sleep(1)

Автор: Adil' 27.10.2004, 13:56
bel_nikita, подозрительно то, что первый вызов Event(dwCommModemStatus); // read from com
будет отрабатывать тогда, когда WaitCommEvent вернет ошибку. Скорее надо наоборот - когда ошибки нет:
Код
 if( !fWaitingOnStat && !WaitCommEvent(m_hPort, &dwCommModemStatus, &m_evStatus) )
 {
   if(GetLastError() == ERROR_IO_PENDING)
     fWaitingOnStat = TRUE;
   //else
       //здесь можно вызвать ClearCommError
 }
 else if(!fWaitingOnStat)
 {
  Event(dwCommModemStatus); // read from com
 }
 ...

SetCommMask (m_hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING); можно смело вынести в Loop() перед while, а GetCommModemStatus, если вообще нужна, логичнее было бы вызывать внутри Event();

З.Ы. а может проще было обойтесь без флага fWaitingOnStat:
Код
void cBarCode::Process()
{
DWORD dwRes = 0;
DWORD dwOvRes = 0;
DWORD dwEvtMask = 0;
 if(WaitCommEvent(m_hPort, &dwEvtMask, &m_evStatus) ||
     ( (GetLastError() == ERROR_IO_PENDING  /*|| ClearCommError(m_hPort,&EvtMask,NULL)*/) &&
       (WaitForSingleObject(m_evStatus.hEvent, 500)==WAIT_OBJECT_0) &&
        GetOverlappedResult(m_hPort, &m_evStatus, &dwOvRes, FALSE)
     )
   )
   Event(dwEvtMask); // read from com
}







Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)