logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak efektywnie synchronizować wątki w WinApi bez użycia WM_TIMER?

Ballbreaker 26 Maj 2010 14:32 1220 1
REKLAMA
  • #1 8119338
    Ballbreaker
    Poziom 12  
    Posty: 71
    Pomógł: 7
    Ocena: 1
    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
  • REKLAMA
  • #2 8134796
    serpent
    Poziom 12  
    Posty: 23
    Pomógł: 3
    Ocena: 2
    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.
REKLAMA