Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Elk stuurprogramma kan een semaphore-object gebruiken om bewerkingen te synchroniseren tussen door het stuurprogramma gemaakte threads en andere stuurprogrammaroutines. Een thread die is toegewezen aan het stuurprogramma, kan zich bijvoorbeeld in een wachtstatus plaatsen wanneer er geen openstaande I/O-aanvragen voor het stuurprogramma zijn en de verzendroutines van het stuurprogramma kunnen de semafore instellen op de status Gesignaleerd net nadat ze een IRP in de wachtrij plaatsen.
De verzendroutines van stuurprogramma's op het hoogste niveau, die worden uitgevoerd in de context van de thread die een I/O-bewerking aanvraagt, kunnen een semaphore gebruiken om een resource te beveiligen die wordt gedeeld tussen de verzendroutines. Stuurprogramma-dispatchroutines op lager niveau voor synchrone I/O-bewerkingen kunnen ook een semafore gebruiken om een resource te beveiligen die wordt gedeeld onder die subset van dispatchroutines of met een thread die door het stuurprogramma is gemaakt.
Elk stuurprogramma dat gebruikmaakt van een semaphore-object moet KeInitializeSemaphore aanroepen voordat het wacht of de semafore vrijgeeft. In de volgende afbeelding ziet u hoe een stuurprogramma met een thread een semaphore-object kan gebruiken.
Zoals in de vorige afbeelding wordt weergegeven, moet een dergelijk stuurprogramma de opslag voor het semaphore-object opgeven, dat moet worden ingezet. Het stuurprogramma kan de apparaatextensie van een apparaatobject dat door het stuurprogramma is gemaakt, de controllerextensie gebruiken als deze gebruikmaakt van een controllerobject, of een niet-gepaginade pool die door het stuurprogramma is toegewezen.
Wanneer de driver AddDevice routine aanroept KeInitializeSemaphore, moet deze een aanwijzer doorgeven aan de residente opslag van het stuurprogramma voor het semaphore-object. Bovendien moet de aanroeper een Count opgeven voor het semaphore-object, zoals wordt weergegeven in de vorige afbeelding, die de oorspronkelijke status (nietzero voor Signaled) bepaalt.
De beller moet ook een Limit opgeven voor de semaphore. Dit kan een van de volgende opties zijn:
Limit = 1
Wanneer deze semaphore is ingesteld op de status Gesignaleerd, komt één thread die wacht tot de semafore is ingesteld op de status Signalering, in aanmerking voor uitvoering en heeft toegang tot elke resource die wordt beveiligd door de semafore.
Dit type semafore wordt ook wel een binaire semafore genoemd omdat een thread wel of niet exclusieve toegang heeft tot de bron die met semaphore is beveiligd.
beperken > 1
Wanneer deze semaphore is ingesteld op de status Signaal, komt een aantal threads die wachten tot het semafore-object is ingesteld op de status Signaal, in aanmerking voor uitvoering en heeft toegang tot elke resource die wordt beveiligd door deemafore.
Dit type semafore wordt een het tellen van semafore genoemd, omdat de routine die de semaphore instelt op de gesignaleerde toestand ook aangeeft hoeveel wachtthreads hun statussen kunnen wijzigen van wachten tot klaar. Het aantal wachtende threads kan de Limiet zijn ingesteld wanneer de semafore is geïnitialiseerd of een getal kleiner is dan deze vooraf ingestelde Limiet.
Weinig apparaat- of tussenstuurprogramma's hebben één thread die door één stuurprogramma is gemaakt; nog minder hebben een set threads die kunnen wachten tot een semafore is verkregen of vrijgegeven. Weinig door het systeem geleverde stuurprogramma's gebruiken semafore-objecten en, van degenen die dat wel doen, nog minder een binaire semafore gebruiken. Hoewel een binaire semaphore lijkt te lijken op een functionaliteit die vergelijkbaar is met een mutex-object, biedt een binaire semafore niet de ingebouwde bescherming tegen impasses die een mutex-object heeft voor systeemthreads die worden uitgevoerd op SMP-machines.
Nadat een stuurprogramma met een geïnitialiseerde semafore is geladen, kunnen bewerkingen worden gesynchroniseerd op de semaphore die een gedeelde resource beveiligt. Een stuurprogramma met een apparaat-toegewezen thread waarmee de wachtrij van IR's, zoals het stuurprogramma van de systeem diskettecontroller, wordt beheerd, kan bijvoorbeeld IRP-wachtrijen synchroniseren op een semaphore, zoals weergegeven in de vorige afbeelding:
De thread roept KeWaitForSingleObject aan met een aanwijzer naar de door het stuurprogramma geleverde opslag voor het geïnitialiseerde semaphore-object om zichzelf in een wachtstatus te plaatsen.
IR's beginnen binnen te komen waarvoor I/O-bewerkingen van apparaten zijn vereist. De verzendroutines van de bestuurder voegen elk van deze IRP in een ingesloten wachtrij in onder spin-lock control en roepen KeReleaseSemaphore met een aanwijzer naar het semaphore-object, een door het stuurprogramma bepaald prioriteitsverhoging voor de thread (Increment, zoals wordt weergegeven in de vorige afbeelding), een Aanpassing van 1 die wordt toegevoegd aan het aantal van de semaphore terwijl elke IRP in de wachtrij wordt geplaatst, en een Booleaanse Wait ingesteld op FALSE. Een niet-nulsemaphore Count stelt het semaphore-object in op de status Signaled, waardoor de status van de wachtthread wordt gewijzigd in gereedheid.
De kernel verzendt de thread voor uitvoering zodra er een processor beschikbaar is: er is momenteel geen andere thread met een hogere prioriteit in de status Gereed en er zijn geen kernelmodusroutines die op een hogere IRQL moeten worden uitgevoerd.
De thread verwijdert een IRP uit de ingesloten wachtrij onder kringvergrendelingsbesturingselement, geeft deze door aan andere stuurprogrammaroutines voor verdere verwerking en aanroepen KeWaitForSingleObject opnieuw. Als de semaphore nog steeds is ingesteld op de status Gesignaleerd (dat wil zeggen, blijft het aantal niet-nul, wat aangeeft dat er meer IRP's in de ingesloten wachtrij van het stuurprogramma staan), verandert de kernel opnieuw de status van de thread totdat deze gereed is.
Door op deze manier een tellingsemafore te gebruiken, is er een IRP die moet worden verwijderd uit de ingesloten wachtrij wanneer die thread wordt uitgevoerd.
Zie de sectie Opmerkingen van KeReleaseSemaphorevoor informatie over het beheren van IRQL bij het aanroepen van KeReleaseSemaphore.
Elke standaardstuurprogrammaroutine die wordt uitgevoerd op een IRQL die groter is dan PASSIVE_LEVEL kan niet wachten op een niet-nulinterval op dispatcherobjecten zonder dat het systeem wordt neergebracht; zie Kernel Dispatcher-objecten voor meer informatie. Een dergelijke routine kan echter KeReleaseSemaphore aanroepen terwijl deze wordt uitgevoerd op een IRQL die kleiner is dan of gelijk is aan DISPATCH_LEVEL.
Zie Hardwareprioriteiten beherenvoor een overzicht van de IRQLs waarop standaardstuurprogrammaroutines worden uitgevoerd. Zie de referentiepagina van de routine voor IRQL-vereisten van een specifieke ondersteuningsroutine.