Uitvoering van meerdere threads synchroniseren
Om racevoorwaarden en impasses te voorkomen, is het noodzakelijk om de toegang van meerdere threads tot gedeelde bronnen te synchroniseren. Synchronisatie is ook nodig om ervoor te zorgen dat interdependent code wordt uitgevoerd in de juiste volgorde.
Er zijn een aantal objecten waarvan de ingangen kunnen worden gebruikt om meerdere threads te synchroniseren. Deze objecten zijn onder andere:
- Console-invoerbuffers
- Gebeurtenissen
- Mutexes
- Processen
- Semaforen
- Draden
- Tijdklokken
De status van elk van deze objecten wordt gesignaleerd of niet gesignaleerd. Wanneer u een ingang opgeeft voor een van deze objecten in een aanroep naar een van de wachtfuncties, wordt de uitvoering van de aanroepende thread geblokkeerd totdat de status van het opgegeven object wordt gesignaleerd.
Sommige van deze objecten zijn handig bij het blokkeren van een thread totdat een bepaalde gebeurtenis plaatsvindt. Een consoleinvoerbuffergreep wordt bijvoorbeeld gesignaleerd wanneer er ongelezen invoer is, zoals een toetsaanslag of muisklik. Proces- en threadgrepen worden gesignaleerd wanneer het proces of de thread wordt beëindigd. Hierdoor kan een proces bijvoorbeeld een onderliggend proces maken en vervolgens de eigen uitvoering blokkeren totdat het nieuwe proces is beëindigd.
Andere objecten zijn handig bij het beveiligen van gedeelde resources tegen gelijktijdige toegang. Meerdere threads kunnen bijvoorbeeld elk een ingang hebben voor een mutex-object. Voordat u toegang krijgt tot een gedeelde resource, moeten de threads een van de wachtfuncties aanroepen om te wachten totdat de status van de mutex wordt gesignaleerd. Wanneer de mutex wordt gesignaleerd, wordt er slechts één wachtthread vrijgegeven voor toegang tot de resource. De status van de mutex wordt onmiddellijk opnieuw ingesteld om niet te worden gesignaleerd, zodat andere wachtende threads geblokkeerd blijven. Wanneer de thread klaar is met het gebruik van de resource, moet de status van de mutex worden ingesteld op gesignaleerd, zodat andere threads toegang kunnen krijgen tot de resource.
Voor de threads van één proces bieden objecten met kritieke secties een efficiëntere synchronisatiewijze dan mutexes. Een kritische sectie wordt als een mutex gebruikt om ervoor te zorgen dat één thread tegelijk gebruik kan maken van de beveiligde bron. Een thread kan de functie EnterCriticalSection gebruiken om het eigendom van een kritieke sectie aan te vragen. Als deze al eigendom is van een andere thread, wordt de aanvraagthread geblokkeerd. Een thread kan de functie TryEnterCriticalSection gebruiken om eigendom van een kritieke sectie aan te vragen, zonder geblokkeerd te worden als het niet lukt om de kritieke sectie te verkrijgen. Nadat het eigendom is verkregen, kan de thread de beschermde bron vrij gebruiken. De uitvoering van de andere threads van het proces wordt niet beïnvloed, tenzij ze proberen dezelfde kritieke sectie te betreden.
De functie WaitForInputIdle laat een thread wachten totdat een gespecificeerd proces is geïnitialiseerd en wacht op gebruikersinvoer zonder hangende invoer. Het aanroepen van WaitForInputIdle kan handig zijn voor het synchroniseren van bovenliggende en onderliggende processen, omdat CreateProcess retourneert zonder te wachten totdat het onderliggende proces de initialisatie heeft voltooid.
Zie Synchronisatievoor meer informatie.