Sincronizzazione dell'esecuzione di più thread
Per evitare condizioni di concorrenza e stalli, è necessario sincronizzare l'accesso da parte di più processi alle risorse condivise. La sincronizzazione è necessaria anche per garantire che il codice interdipendente venga eseguito nella sequenza corretta.
Esistono diversi oggetti i cui handle possono essere usati per sincronizzare più thread. Questi oggetti includono:
- Buffer di input della console
- Avvenimenti
- Mutex
- Processi
- Semafori
- Discussioni
- Timer
Lo stato di ognuno di questi oggetti viene segnalato o non segnalato. Quando si specifica un handle per uno di questi oggetti in una chiamata a una delle funzioni di attesa , l'esecuzione del thread chiamante viene bloccata fino a quando lo stato dell'oggetto specificato non viene segnalato.
Alcuni di questi oggetti sono utili per bloccare un thread fino a quando non si verifica un evento. Ad esempio, un handle di buffer di input della console diventa attivo quando viene rilevato un input non letto, come una sequenza di tasti o un clic del pulsante del mouse. Gli handle di processo e thread vengono segnalati quando il processo o il thread termina. In questo modo un processo, ad esempio, può creare un processo figlio e quindi bloccarne la propria esecuzione fino a quando il nuovo processo non viene terminato.
Altri oggetti sono utili per proteggere le risorse condivise dall'accesso simultaneo. Ad esempio, più thread possono avere un handle per un oggetto mutex. Prima di accedere a una risorsa condivisa, i thread devono chiamare una delle funzioni di attesa affinché lo stato del mutex venga segnalato. Quando il mutex diventa attivo, viene rilasciato un solo thread in attesa per accedere alla risorsa. Lo stato del mutex viene immediatamente reimpostato su "non segnalato", in modo che qualsiasi altro thread in attesa rimanga bloccato. Quando il thread ha finito di utilizzare la risorsa, deve impostare lo stato del mutex su segnalato per consentire ad altri thread di accedere alla risorsa.
Per i thread di un singolo processo, gli oggetti sezione critica forniscono un mezzo di sincronizzazione più efficiente rispetto ai mutex. Una sezione critica viene usata come un mutex per abilitare un thread alla volta per usare la risorsa protetta. Un thread può usare la funzioneenterCriticalSectionper richiedere la proprietà di una sezione critica. Se è già di proprietà di un altro thread, il thread richiedente viene bloccato. Un thread può usare la funzione TryEnterCriticalSection per richiedere la proprietà di una sezione critica, senza bloccarsi in caso di mancato ottenimento della sezione critica. Dopo aver ricevuto la proprietà, il thread è libero di usare la risorsa protetta. L'esecuzione degli altri thread del processo non è interessata, a meno che non tentino di entrare nella stessa sezione critica.
La funzione WaitForInputIdle fa sì che un thread attenda fino a quando un processo specificato non viene inizializzato e sta aspettando l'input dell'utente senza nessun input in sospeso. La chiamata WaitForInputIdle può essere utile per sincronizzare i processi padre e figlio, perché CreateProcess restituisce senza attendere che il processo figlio completi la sua inizializzazione.
Per altre informazioni, vedere Synchronization.