Asynchrone procedureaanroepen
Een asynchrone procedureaanroep (APC) is een functie die asynchroon wordt uitgevoerd in de context van een bepaalde thread. Wanneer een APC in de wachtrij wordt geplaatst voor een thread, geeft het systeem een software-interrupt uit. De volgende keer dat de thread wordt gepland, wordt de APC-functie uitgevoerd. Een APC die door het systeem wordt gegenereerd, wordt een APC-genoemd. Een APC die door een toepassing wordt gegenereerd, wordt een APC-in de gebruikersmodus genoemd. Een thread moet een waarschuwingsstatus hebben om een APC in de gebruikersmodus uit te voeren.
Elke thread heeft een eigen APC-wachtrij. Een toepassing zet een APC in de wachtrij voor een thread door de QueueUserAPC--functie aan te roepen. De aanroepende thread geeft het adres van een APC-functie in de aanroep naar QueueUserAPC. De wachtrij van een APC is een aanvraag voor de thread om de APC-functie aan te roepen.
Wanneer een APC in de gebruikersmodus in de wachtrij wordt geplaatst, wordt de thread waarnaar deze in de wachtrij wordt geplaatst, niet omgeleid om de APC-functie aan te roepen, tenzij deze een waarschuwingsstatus heeft. Een thread voert een waarschuwingsstatus in wanneer deze de SleepEx-aanroept, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsExof WaitForSingleObjectEx functie. Als aan de wacht wordt voldaan voordat de APC in de wachtrij wordt geplaatst, heeft de thread geen waarschuwingsstatus meer, zodat de APC-functie niet wordt uitgevoerd. De APC wordt echter nog steeds in de wachtrij geplaatst, dus de APC-functie wordt uitgevoerd wanneer de thread een andere waarschuwingsfunctie aanroept.
De ReadFileEx, SetWaitableTimer, SetWaitableTimerExen WriteFileEx--functies worden geïmplementeerd met behulp van een APC als het callbackmechanisme voor voltooiingsmeldingen.
Als u een threadgroep gebruikt, moet u er rekening mee houden dat APC's niet goed werken en andere signaleringsmechanismen omdat het systeem de levensduur van threadgroepthreads beheert, zodat het mogelijk is dat een thread wordt beëindigd voordat de melding wordt bezorgd. Gebruik in plaats van een op APC gebaseerde signaleringsmechanisme zoals de parameter pfnCompletionRoutine parameter van SetWaitableTimer- of SetWaitableTimerExeen wachtbaar object zoals een timer die is gemaakt met CreateThreadpoolTimer-. Gebruik voor I/O een I/O-voltooiingsobject dat is gemaakt met CreateThreadpoolIo of een hEvent-based OVERLAPPED structuur waar de gebeurtenis kan worden doorgegeven aan de SetThreadpoolWait--functie.
Interne synchronisatie
Wanneer een I/O-aanvraag wordt uitgegeven, wordt er een structuur toegewezen om de aanvraag weer te geven. Deze structuur wordt een I/O-aanvraagpakket (IRP) genoemd. Met synchrone I/O bouwt de thread de IRP, verzendt deze naar de apparaatstack en wacht in de kernel totdat de IRP is voltooid. Met asynchrone I/O bouwt de thread de IRP en verzendt deze naar de apparaatstack. De stack kan de IRP onmiddellijk voltooien of er kan een status in behandeling worden geretourneerd die aangeeft dat de aanvraag wordt uitgevoerd. Als dit gebeurt, is het IRP nog steeds gekoppeld aan de thread, dus wordt deze geannuleerd als de thread wordt beëindigd of een functie aanroept, zoals CancelIo-. Ondertussen kan de thread andere taken blijven uitvoeren terwijl de apparaatstack de IRP blijft verwerken.
Er zijn verschillende manieren waarop het systeem kan aangeven dat de IRP is voltooid:
- Werk de overlappende structuur bij met het resultaat van de bewerking, zodat de thread kan peilen om te bepalen of de bewerking is voltooid.
- Signaler de gebeurtenis in de overlappende structuur, zodat een thread op de gebeurtenis kan synchroniseren en wordt wakker wanneer de bewerking is voltooid.
- Zet de IRP in de wachtrij van de thread in behandeling met APC, zodat de thread de APC-routine uitvoert wanneer deze een waarschuwingsstatus invoert en terugkeert van de wachtbewerking met een status die aangeeft dat er een of meer APC-routines zijn uitgevoerd.
- Zet de IRP in de wachtrij op een I/O-voltooiingspoort, waar deze wordt uitgevoerd door de volgende thread die wacht op de voltooiingspoort.
Threads die wachten op een I/O-voltooiingspoort, wachten niet in een waarschuwingsstatus. Als deze threads DAAROM IR's uitgeven die zijn ingesteld om te worden voltooid als API's voor de thread, vinden deze IPC-voltooiingen niet tijdig plaats; ze vinden alleen plaats als de thread een aanvraag ophaalt van de I/O-voltooiingspoort en vervolgens een waarschuwingswacht wordt ingevoerd.
Verwante onderwerpen