Qual è la differenza tra un lucchetto esclusivo e un lucchetto condiviso?


119

Secondo wikipedia,

I blocchi condivisi sono talvolta chiamati "blocchi di lettura" e i blocchi esclusivi sono talvolta chiamati "blocchi di scrittura".

Puoi spiegare il ragionamento alla base dei termini "condiviso" ed "esclusivo"?


Il blocco non esclusivo è un altro nome del blocco condiviso?
Ramesh Papaganti

Risposte:


419

Ho scritto questa risposta perché pensavo che sarebbe stata un'analogia divertente (e calzante):

Pensa a un oggetto chiudibile a chiave come una lavagna (chiudibile a chiave) in un'aula contenente un insegnante (scrittore) e molti studenti (lettori).

Mentre un insegnante scrive qualcosa (lucchetto esclusivo) sulla lavagna:

  1. Nessuno può leggerlo, perché è ancora in fase di scrittura e lei sta bloccando la tua visualizzazione => Se un oggetto è bloccato esclusivamente, non è possibile ottenere blocchi condivisi .

  2. Anche gli altri insegnanti non si avvicineranno e inizieranno a scrivere, oppure la lavagna diventa illeggibile e confonde gli studenti => Se un oggetto è bloccato esclusivamente, non è possibile ottenere altri blocchi esclusivi .

Quando gli studenti stanno leggendo (lucchetti condivisi) cosa c'è sulla lavagna:

  1. Tutti possono leggere cosa c'è sopra, insieme => Possono coesistere più blocchi condivisi .

  2. L'insegnante aspetta che finiscano di leggere prima di liberare la lavagna per scrivere altro => Se uno o più blocchi condivisi esistono già, non è possibile ottenere blocchi esclusivi .


2
spiegazione molto buona. Tuttavia, l'OP ha chiesto l' origine delle denominazioni "condivise" ed "esclusive", non una spiegazione delle termiche in sé.
serhio

È "Se uno o più blocchi condivisi esistono già, non è possibile ottenere blocchi esclusivi". è vero? interms di ReentrantReadWriteLock? Pensavo che il blocco della scrittura potesse essere ottenuto in qualsiasi momento, altrimenti la fame di scrittura potrebbe verificarsi a causa della lettura continua.
Kanagavelu Sugumar

1
@KanagaveluSugumar, sì, è vero. Semplicemente non puoi ottenere un blocco in scrittura quando un'altra entità possiede già un blocco in lettura sullo stesso oggetto. Questo è il punto centrale di un blocco lettura-scrittura. Se ti capita di sovrascrivere qualcosa mentre qualcun altro lo sta leggendo, cosa leggerebbero? Non so perché hai scelto di scegliere specificamente un blocco di lettura / scrittura "rientrante", ma re-entrancy significa che il proprietario di un lucchetto di rientro può "bloccarlo ()" di nuovo e tutte le lock()chiamate successive dopo il primo tornerà immediatamente e con successo. cioè puoi bloccare con successo qualcosa che già possiedi.
ArjunShankar,

2
Hai anche detto che "Pensavo che il blocco della scrittura potesse essere ottenuto in qualsiasi momento, altrimenti la fame di scrittura potrebbe verificarsi a causa della lettura continua" - questo semplicemente non può essere. Non è possibile ottenere un blocco di scrittura mentre un'altra entità possiede già un blocco di lettura / scrittura. Ciò che può accadere è che se più entità sono già in attesa di bloccare un oggetto, writerviene data la preferenza a un'attesa rispetto ai lettori in attesa quando il blocco sceglie chi ottiene il blocco successivo (quando viene sbloccato dal suo attuale proprietario). Si tratta di politica .
ArjunShankar

Grazie! Ho scelto ReentrantReadWriteLock; poiché questa è la classe di implementazione per ReadWriteLock in java. Quindi c'è qualche flag sollevato o più priorità impostata per dire ulteriori nuovi thread di lettura da attendere quando il thread di scrittura viene avviato in attesa? Perché come evitare la fame di thread di scrittura a causa della continua richiesta di lettura?
Kanagavelu Sugumar

34

È abbastanza semplice. I blocchi di lettura sono noti anche come blocchi condivisi perché più di un processo può leggere contemporaneamente. Lo scopo di un blocco di lettura è impedire l'acquisizione di un blocco di scrittura da parte di un altro processo. Al contrario, un blocco di scrittura inibisce tutte le altre operazioni mentre un'operazione di scrittura viene completata, motivo per cui viene descritta come esclusiva.

Quindi un lucchetto in lettura dice "puoi leggere adesso ma se vuoi scrivere dovrai aspettare" mentre un lucchetto in scrittura dice "dovrai aspettare".


Mi rendo conto che stai facendo ricerche a sostegno dei tuoi studi, ma non posso resistere all'impulso di tenere una conferenza.

L'uso incompetente del bloccaggio è una delle principali cause di mal di testa da prestazione. L'uso di un sistema di blocco che differenzia i blocchi di lettura e scrittura è un buon inizio, ma un'attenta progettazione a volte può eliminare gran parte della necessità di bloccare. Ad esempio, lo stato della sessione non dovrebbe mai essere contenuto in una raccolta globale per elemento di stato.

L'ho effettivamente visto fare. È un design atroce, che causa boxe e una modifica a una collezione per ogni ultima modifica allo stato della sessione, comportando un blocco di scrittura prolungato. I costi generali erano paralizzanti, riducendo efficacemente il server a un comportamento a thread singolo.

La semplice aggregazione di tutto lo stato della sessione in una struttura è stato un enorme miglioramento. Le modifiche allo stato della sessione hanno semplicemente modificato i valori dei membri della struttura dello stato di una sessione. Poiché nessun'altra sessione ha avuto occasione o anche l'opportunità di fare riferimento direttamente allo stato di una sessione, l'unica raccolta aggiornata era l'elenco delle sessioni. Di conseguenza, il blocco era completamente inutile durante una sessione, solo all'inizio e alla fine, e il throughput è aumentato di un fattore di 3000.

L'altro scenario di blocco comune sono le risorse condivise tra i thread di un'applicazione utente. La maggior parte dei framework moderni risolve questo problema utilizzando messaggi anziché blocchi; quando si "passa al thread UI" si sta effettivamente accodando un messaggio contenente un puntatore a funzione e alcuni parametri (o un delegato e uno stack frame a seconda dell'implementazione).


6
  • Un blocco esclusivo o in scrittura fornisce a un processo l'accesso esclusivo per la scrittura nella parte specificata del file. Mentre è attivo un blocco di scrittura, nessun altro processo può bloccare quella parte del file.

  • Un blocco condiviso o di lettura impedisce a qualsiasi altro processo di richiedere un blocco di scrittura sulla parte specificata del file. Tuttavia, altri processi possono richiedere blocchi di lettura.

Altro su questo: http://www.gnu.org/software/libc/manual/html_node/File-Locks.html


2

Principio lo stesso anche sul lato database. Come da documentazione Oracle

La modalità di blocco esclusivo impedisce la condivisione della risorsa associata. Questa modalità di blocco si ottiene per modificare i dati. La prima transazione per bloccare esclusivamente una risorsa è l'unica transazione che può alterare la risorsa finché non viene rilasciato il blocco esclusivo.

La modalità di blocco condivisione consente di condividere la risorsa associata, a seconda delle operazioni coinvolte. Più utenti che leggono i dati possono condividere i dati, mantenendo i blocchi di condivisione per impedire l'accesso simultaneo da parte di un writer (che necessita di un blocco esclusivo). Diverse transazioni possono
acquisire blocchi di condivisione sulla stessa risorsa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.