c ++ - venter på tid at passere uden travlt at vente i C-vinduer

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har en tråd, hvis job er at sende beskeder til UDP-kolleger. trådene sender meddelelserne iff et af følgende gælder:


1) Der er gået en vis tid siden sidste gang, den sendte en besked (som en timeout).


2) En opdatering boolsk flag i en delt struct er blevet rejst af anden tråd.


Jeg vil gerne være i stand til at vente på, at disse betingelser vil ske, så jeg ved, hvornår jeg skal sende beskeden.


Den enkleste måde jeg kan gøre er ved at lave en loop, der gentages, indtil en af ​​betingelserne opfylder. Jeg er bange for, at det er travlt med at vente og vil forbruge en masse CPU-tid for ingenting. Jeg vil heller ikke bruge søvn ().


Jeg har ikke noget imod en C ++-løsning, så længe det er let at forstå og implementere, da jeg ikke er meget bekendt med C ++.


Tak!

Bedste reference


For windows skal du bruge en begivenhed (CreateEvent) i stedet for en bool, så WaitForSingleObject på den.

Andre referencer 1


For signalet mellem trådene er jeg enig med Erik. Brug et hændelsesobjekt.


For timeout-problemet kan du bruge CreateWaitableTimer () og SetWaitableTimer (). [4]


For at vente i tråden for at begivenheden bliver signaleret eller timeren løber ud, kan du bruge ventetiden WaitForMultipleObjects (). Du kan passere en række håndtag (= håndtere til begivenhed og håndtere timer) til at vente på, at de bliver signaleret.


Ventfunktionerne har den fordel, at man ikke bruger op CPU'en, ligesom en afstemningsløkke ville gøre, da venterne håndteres på kerneniveauet, og tråden bliver suspenderet, mens den venter på, at et objekt bliver signaleret.

Andre referencer 2


Du vil sandsynligvis bruge en tilbagekaldelsesrutine indlejret i tråden. Se Hvad er en 'tilbagekald' i C og hvordan implementeres de? for en forklaring og tjek C-eksemplet i dette wiki-eksempel, som implementerer et tilbagekald som en funktionspeger. Det er nemmere at bruge en begivenhedsramme af en eller anden type (som foreslået af Erik et al.) I stedet for at rulle dit eget, men det er en god færdighed at have i din taske med tricks. [6]

Andre referencer 3


Jeg ville bruge WaitForMultipleObjects, lytte til 2 events
Den første ville være at afslutte tråden og den anden til at udføre arbejdet.


Noget sådan her ...


DWROD dwTimeOut = .....;


DWORD dwRetValue = WaitForMultipleObjects(2, hEvents, false, dwTimeOut);

if( (dwRetValue ==  WAIT\_TIMEOUT) || (dwRetValue == (WAIT\_OBJECT\_0 + 1)))
{
  // Do Work

}
else if(dwRetValue == WAIT\_OBJECT\_0)
{
  // End Thread

}
else
{
  // Deal with Error
}