Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Efektywne wykorzystanie wątków WinApi

Ballbreaker 26 May 2010 14:32 1067 1
  • #1
    Ballbreaker
    Level 12  
    Witam !

    Mam sobie program, w którym każdy z wątków monitoruje jeden adres IP.

    Po odpaleniu, wątek ustawia sobie timer na zadany czas, a potem czeka w pętli na mesga WM_TIMER. Czeka uśpiony (mam nadizeję) gdyż konstrukcję mam
    while(GetMessage(&msg, NULL, 0, 0))


    Dziś przeczytałem w MSDN, że nieefektywne jest ustawienie, kiedy odpali się dużo wątków i każdy z nich czeka na msg. Czy moglibyście powiedzieć coś wiecej na ten temat?

    Czy istnieją lepsze, bardziej efektywne sposoby zmuszenia wątków do zsynchronizowanej pracy?


    Pozdro
  • #2
    serpent
    Level 12  
    Na MSDN znalazłem taką funkcję

    
    DWORD WINAPI MsgWaitForMultipleObjects(
      __in  DWORD nCount,
      __in  const HANDLE *pHandles,
      __in  BOOL bWaitAll,
      __in  DWORD dwMilliseconds,
      __in  DWORD dwWakeMask
    );
    


    Jeżeli ustawisz dwWakeMask na QS_TIMER to funkcja czeka na wiadomości WM_TIMER. Nie wiem dokładnie, bo nigdy nie używałem tej funkcji.

    Jeżeli nie, to zawsze możesz użyć funkcji WaitForSingleObject, z tym że funkcja ta nie działa z timerami tworzonymi przez SetTimer.
    Musiałbyś stworzyć event:
    
    HANDLE hevent=CreateEvent(NULL, true, false, NULL);
    

    Tworzysz timer funkcją SetTimer.
    Później wywołujesz
    
    WaitForSingleObject(hevent, INFINITE);
    

    Funkcja będzie czekać na stan sygnalizowany (stan "wysoki") obiektu hevent.
    Stan taki wywołujesz ręcznie w procedurze obsługi wiadomości WM_TIMER:
    
    bool TimerProc(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime)
    {
    if (msg==WM_TIMER)
      {
      SetEvent(hevent);
      }
    }
    

    SetEvent(hevent) spowoduje, że funkcja WaitForSingleObject przestanie oczekiwać i zwróci wartość WAIT_OBJECT_0. Za tą funkcją wywołujesz więc (w pętli)
    
    while (true)
      {
      WaitForSingleObject(hevent, INFINITE);
      ResetEvent(hevent);
      // tutaj twój kod
      }
    


    Trochę to skomplikowane, ale wymyśliłem to teraz, nigdy nie używałem takiego kodu.
    Nie daję żadnej gwarancji, ale mam nadzieję że choć trochę pomogłem.