I mutex sono assegnati a specifiche regioni di memoria?

3

Attualmente sto leggendo C ++ Concurrency in Action di Anthony Williams e sto affrontando un ostacolo di riflessione.

Per prima cosa descrive deadlock come quando due thread si bloccano simultaneamente (almeno, è così che l'ho capito), il che ha senso.

Tuttavia, continua a spiegare come è possibile bloccare due mutex allo stesso tempo. Ovviamente questo ha una funzione, ma con la comprensione sopra (presumibilmente sbagliata) che avrebbe istantaneamente bloccato entrambi i thread.

Da quell'ostacolo ne nasce uno nuovo; ovviamente non si bloccherà, il che significa che i mutex devono avere un uso più avanzato del semplice consentire a un singolo thread di lavorare in un processo. Nel libro, i mutex sono dati a oggetti particolari.

Questo mi porta alle mie domande generali: I mutex sono assegnati a regioni di memoria specifiche , come oggetti? Se sì, come?

Il libro svolge un ottimo lavoro nello spiegare come i mutex possono essere usati, ma non descrive mai realmente quali mutex sono a un livello basso. Mi rendo conto che sono specifici per l'implementazione, ma non ho mai capito veramente cosa fanno esattamente o come le funzioni di blocco li usano.

    
posta Qix 16.09.2013 - 21:58
fonte

1 risposta

5

Un mutex non è una regione di memoria specifica; è un segnale, fondamentalmente un tipo speciale di oggetto, e funziona semplicemente "sul sistema d'onore", per così dire. Un mutex protegge una regione di codice perché le chiamate ad esso circondano il codice in questione, non perché ha una relazione intrinseca al codice. (Anche quando si tratta di un blocco associato a un oggetto, come con la parola chiave lock di C #, i blocchi funzionano solo quando vengono richiamati da una parte di codice.)

Ci sono due cose che possono accadere quando un pezzo di codice tenta di acquisire un lock: o lo può trovare disponibile e acquisire il lock, oppure può trovarlo già in uso e fallire. La risposta più comune al fallimento è aspettare fino a quando il blocco diventa disponibile. E un deadlock non si verifica perché due thread stanno entrambi tentando di utilizzare un blocco nello stesso momento; succede perché due thread sono entrambi waiting on each other allo stesso tempo.

Immagina che esistano due blocchi, chiamati A e B , e che esistano due thread, chiamati 1 e 2. Entrambi stanno facendo cose che richiedono l'accesso bloccato sia a A che a B , ma thread 1 contiene A e il thread 2 contiene B . Se entrambi cercano di acquisire l'altro lucchetto, e poi (come è normale) tentano di aspettare per sempre finché non diventa disponibile, entrambi rimarranno bloccati in attesa per sempre (bloccati a fondo).

Il modo migliore per prevenire una situazione come questa è identificare situazioni in cui il codice potrebbe dover contenere più di un blocco alla volta e imporre una sorta di regola di ordinamento generale sull'intera base di codice, in modo che nessun thread possa acquisire più blocchi simultanei fuori servizio. Se nessun thread che ha bisogno di A e B può acquisire B senza già detenere A , ad esempio, è impossibile rimanere bloccati nel deadlock descritto sopra.

A un livello basso, un mutex può essere pensato come contenente due pezzi di dati: una variabile che identifica il titolare corrente, come un numero ID del thread (o 0 se è attualmente sbloccato) e una sorta di elenco di thread che sono attualmente in attesa su di esso. L'accesso a questi dati è controllato dalle operazioni atomiche , per garantire che più thread che tentano di acquisire il mutex non sovrascrivano o corrompano ogni altro.

    
risposta data 16.09.2013 - 23:42
fonte

Leggi altre domande sui tag