Wachtfuncties
Wachtfuncties toestaan dat een thread een eigen uitvoering blokkeert. De wachtfuncties worden pas geretourneerd als aan de opgegeven criteria is voldaan. Het type wachtfunctie bepaalt de set gebruikte criteria. Wanneer een wachtfunctie wordt aangeroepen, wordt gecontroleerd of aan de wachtcriteria is voldaan. Als niet aan de criteria is voldaan, voert de aanroepende thread de wachtstatus in totdat aan de voorwaarden van de wachtcriteria is voldaan of het opgegeven time-outinterval is verstreken.
- Wachtfuncties met één object
- Functies voor meerdere objecten wachten
- waarschuwingsfuncties
- geregistreerde wachtfuncties
- wachten op een adres
- wachtfuncties en time-outintervallen
- wachtfuncties en synchronisatieobjecten
- Wachtfuncties en Windows- maken
Wachtfuncties voor één object
De SignalObjectAndWait-, WaitForSingleObjecten WaitForSingleObjectEx--functies vereisen een ingang naar één synchronisatieobject. Deze functies worden geretourneerd wanneer een van de volgende situaties plaatsvindt:
- Het opgegeven object heeft de gesignaleerde status.
- Het time-outinterval is verstreken. Het time-outinterval kan worden ingesteld op INFINITE- om op te geven dat er geen time-out optreedt voor de wachttijd.
Met de functie SignalObjectAndWait kan de aanroepende thread de status van een object atomisch instellen om te signaleren en te wachten totdat de status van een ander object is ingesteld op gesignaleerd.
Wachtfuncties voor meerdere objecten
De WaitForMultipleObjects, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsen MsgWaitForMultipleObjectsEx- kunnen de aanroepende thread een matrix opgeven die een of meer synchronisatieobjectingangen bevat. Deze functies worden geretourneerd wanneer een van de volgende situaties plaatsvindt:
- De status van een van de opgegeven objecten is ingesteld op gesignaleerd of de statussen van alle objecten zijn ingesteld op gesignaleerd. U bepaalt of een of alle statussen worden gebruikt in de functie-aanroep.
- Het time-outinterval is verstreken. Het time-outinterval kan worden ingesteld op INFINITE- om op te geven dat er geen time-out optreedt voor de wachttijd.
Met de functie MsgWaitForMultipleObjects en MsgWaitForMultipleObjectsEx kunt u invoergebeurtenisobjecten opgeven in de objecthandlermatrix. Dit wordt gedaan wanneer u het type invoer opgeeft dat moet worden gewacht in de invoerwachtrij van de thread. Een thread kan bijvoorbeeld MsgWaitForMultipleObjects gebruiken om de uitvoering te blokkeren totdat de status van een opgegeven object is ingesteld op signalering en er muisinvoer beschikbaar is in de invoerwachtrij van de thread. De thread kan de GetMessage- of PeekMessageA- of functie PeekMessageW gebruiken om de invoer op te halen.
Wanneer wordt gewacht tot de statussen van alle objecten zijn ingesteld op gesignaleerd, wijzigen deze functies met meerdere objecten de statussen van de opgegeven objecten pas nadat de statussen van alle objecten zijn ingesteld. De status van een mutex-object kan bijvoorbeeld worden gesignaleerd, maar de aanroepende thread krijgt geen eigendom totdat de statussen van de andere objecten die in de matrix zijn opgegeven, ook zijn ingesteld op gesignaleerd. In de tussentijd kan een andere thread het eigendom van het mutex-object krijgen, waardoor de status wordt ingesteld op niet-ondertekend.
Wanneer u wacht tot de status van één object is ingesteld op gesignaleerd, controleren deze functies met meerdere objecten de ingangen in de matrix in volgorde van index 0 totdat een van de objecten wordt gesignaleerd. Als meerdere objecten worden gesignaleerd, retourneert de functie de index van de eerste ingang in de matrix waarvan het object is gesignaleerd.
Waarschuwingsfuncties
De MsgWaitForMultipleObjectsEx, SignalObjectAndWait, WaitForMultipleObjectsExen WaitForSingleObjectEx functies verschillen van de andere wachtfuncties, omdat ze desgewenst een waarschuwingsbewerking kunnen uitvoeren. In een waarschuwingsbare wachtbewerking kan de functie retourneren wanneer aan de opgegeven voorwaarden wordt voldaan, maar kan deze ook worden geretourneerd als het systeem een I/O-voltooiingsroutine of een APC voor uitvoering door de wachtthread uitvoert. Zie Synchronisatie en overlappende invoer- en uitvoer-voor meer informatie over waarschuwingsbewerkingen en I/O-voltooiingsroutines. Zie Asynchrone procedureaanroepenvoor meer informatie over API's.
Geregistreerde wachtfuncties
De RegisterWaitForSingleObject functie verschilt van de andere wachtfuncties omdat de wachtbewerking wordt uitgevoerd door een thread uit de threadpool. Wanneer aan de opgegeven voorwaarden wordt voldaan, wordt de callback-functie uitgevoerd door een werkrolthread uit de threadpool.
Standaard is een geregistreerde wachtbewerking een bewerking met meerdere wachttijden. Het systeem stelt de timer opnieuw in telkens wanneer de gebeurtenis wordt gesignaleerd (of het time-outinterval is verstreken) totdat u de UnregisterWaitEx--functie aanroept om de bewerking te annuleren. Als u wilt opgeven dat een wachtbewerking slechts één keer moet worden uitgevoerd, stelt u de parameter dwFlags in van RegisterWaitForSingleObject- in op WT_EXECUTEONLYONCE.
Als de thread functies aanroept die gebruikmaken van API's, stelt u de dwFlags-parameter in van RegisterWaitForSingleObject- in op WT_EXECUTEINPERSISTENTTHREAD.
Wachten op een adres
Een thread kan de WaitOnAddress-functie gebruiken om te wachten tot de waarde van een doeladres wordt gewijzigd van een ongewenste waarde in een andere waarde. Hierdoor kunnen threads wachten tot een waarde wordt gewijzigd zonder dat ze de synchronisatieproblemen hoeven te draaien of afhandelen die kunnen optreden wanneer de thread een ongewenste waarde vastlegt, maar de waarde verandert voordat de thread kan wachten.
WaitOnAddress retourneert wanneer code die de doelwaarde wijzigt de wijziging aangeeft door WakeByAddressSingle- aan te roepen om één wachtthread te activeren of WakeByAddressAll om alle wachtende threads te activeren. Als er een time-outinterval wordt opgegeven met WaitOnAddress- en er geen thread een wake-functie aanroept, wordt de functie geretourneerd wanneer het time-outinterval is verstreken. Als er geen time-outinterval is opgegeven, wacht de thread voor onbepaalde tijd.
Wachtfuncties en time-outintervallen
De nauwkeurigheid van het opgegeven time-outinterval is afhankelijk van de resolutie van de systeemklok. De systeemklok "tikt" met een constante snelheid. Als het time-outinterval kleiner is dan de resolutie van de systeemklok, kan er een time-out optreden in minder dan de opgegeven tijdsduur. Als het time-outinterval groter is dan één maatstreepje, maar kleiner dan twee, kan de wachttijd ergens tussen één en twee tikken zijn, enzovoort.
Als u de nauwkeurigheid van het time-outinterval voor de wachtfuncties wilt verhogen, roept u de timeGetDevCaps functie aan om de ondersteunde minimale timerresolutie en de timeBeginPeriod--functie te bepalen om de timerresolutie in te stellen op het minimum. Wees voorzichtig bij het aanroepen van timeBeginPeriod, omdat frequente aanroepen de systeemklok, het systeemstroomgebruik en de planner aanzienlijk kunnen beïnvloeden. Als u timeBeginPeriodaanroept, roept u deze één keer vroeg in de toepassing aan en roept u de timeEndPeriod functie aan het einde van de toepassing aan.
Wachtfuncties en synchronisatieobjecten
De wachtfuncties kunnen de statussen van bepaalde typen synchronisatieobjectenwijzigen. Wijziging vindt alleen plaats voor het object of de objecten waarvan de gesignaleerde status de functie heeft geretourneerd. Wachtfuncties kunnen de statussen van synchronisatieobjecten als volgt wijzigen:
- Het aantal van een semaphore-object neemt af met één en de toestand van deemafore wordt ingesteld op niet-ondertekend als het aantal nul is.
- De statussen van mutex, gebeurtenis voor automatisch opnieuw instellen en objecten voor wijzigingsmeldingen worden ingesteld op niet-ondertekend.
- De status van een synchronisatietimer is ingesteld op niet-ondertekend.
- De statussen van handmatig opnieuw instellen van gebeurtenissen, timer voor handmatig opnieuw instellen, proces, thread en console-invoerobjecten worden niet beïnvloed door een wachtfunctie.
Wachtfuncties en windows maken
U moet voorzichtig zijn bij het gebruik van de wachtfuncties en code die direct of indirect vensters maakt. Als een thread vensters maakt, moet deze berichten verwerken. Berichtuitzendingen worden verzonden naar alle vensters in het systeem. Als u een thread hebt die gebruikmaakt van een wachtfunctie zonder time-outinterval, loopt het systeem vast. Twee voorbeelden van code die indirect vensters maakt, zijn DDE en de CoInitialize functie. Als u daarom een thread hebt die vensters maakt, gebruikt u MsgWaitForMultipleObjects of MsgWaitForMultipleObjectsEx, in plaats van de andere wachtfuncties.