2009-08-21 19 views

risposta

125

rientrante bloccaggio

Serratura rientrante è quella in cui un processo può rivendicazione molteplici volte serratura senza bloccare su se stessa. È utile in situazioni in cui non è facile tenere traccia di se hai già preso un lucchetto. Se un lucchetto non è rientrante, puoi afferrare il lucchetto, quindi bloccarlo quando lo riprendi, bloccando in modo efficace il tuo processo.

Rientranza, in generale, è una proprietà di codice in cui non ha stato mutevole centrale che potrebbe essere danneggiato se il codice è stato chiamato mentre è in esecuzione. Tale chiamata potrebbe essere effettuata da un altro thread, oppure potrebbe essere effettuata in modo ricorsivo da un percorso di esecuzione proveniente dal codice stesso.

Se il codice si basa su stato condiviso che potrebbe essere aggiornato nel bel mezzo della sua esecuzione non è ri-concorrente, almeno non se questo aggiornamento potrebbe romperlo.

Un caso d'uso per rientrante bloccaggio

A (piuttosto generica e artificiosa) esempio di applicazione di un blocco rientrante potrebbe essere:

  • Hai qualche tipo di calcolo che coinvolgono un algoritmo che attraversa un grafico (forse con cicli in esso). Un attraversamento può visitare lo stesso nodo più di una volta a causa dei cicli o a causa di più percorsi allo stesso nodo.

  • La struttura dei dati è soggetto ad accesso concorrente e potrebbe essere aggiornato per qualche motivo, forse da un altro thread. Devi essere in grado di bloccare singoli nodi per far fronte al potenziale danneggiamento dei dati a causa delle condizioni di gara. Per qualche ragione (forse per prestazioni) non vuoi bloccare globalmente l'intera struttura dati.

  • Il calcolo non è in grado di conservare informazioni complete su quali nodi si sono visitati o si sta utilizzando una struttura dati che non consente di rispondere rapidamente alle domande "Sono stato qui prima".

    Un esempio di questa situazione sarebbe una semplice implementazione dell'algoritmo di Dijkstra con una coda di priorità implementata come un heap binario o una ricerca in ampiezza utilizzando una lista collegata semplice come una coda. In questi casi, la scansione della coda per gli inserimenti esistenti è O (N) e potresti non volerlo eseguire su ogni iterazione.

In questa situazione, tenere traccia di quali lucchetti sono già stati acquistati è costoso. Supponendo che si desideri eseguire il blocco a livello di nodo, un meccanismo di blocco rientrante riduce la necessità di stabilire se si è già visitato un nodo. Puoi bloccare ciecamente il nodo, magari sbloccandolo dopo averlo fatto uscire dalla coda.

rientrante mutexes

Un semplice mutex non rientrante come solo un thread può essere nella sezione critica in un dato momento è. Se prendi il mutex e poi provi ad afferrarlo di nuovo, un semplice mutex non ha abbastanza informazioni per dire chi lo stava tenendo in precedenza. Per fare questo in modo ricorsivo è necessario un meccanismo in cui ogni thread ha un token in modo da poter dire chi ha afferrato il mutex. Questo rende il meccanismo mutex un po 'più costoso, quindi potresti non volerlo fare in tutte le situazioni.

IIRC l'API di thread POSIX offre l'opzione di mutex re-entrant e non re-entrant.

+1

Anche se tali situazioni dovrebbero essere evitate in ogni caso, in quanto rende difficile evitare deadlock ecc. Il threading è abbastanza difficile comunque senza essere in dubbio sul fatto che tu abbia già una serratura. –

+0

+1, considera anche il caso in cui il blocco NON è rientranti, puoi bloccarti su te stesso se non stai attento. In più in C, non hai gli stessi meccanismi che fanno gli altri linguaggi per garantire che il blocco venga rilasciato tutte le volte che viene acquisito. Questo può portare a grossi problemi. – user7116

+1

è esattamente quello che mi è successo ieri: non ho preso in considerazione la questione della ri-entrancy e ho finito con il debug di un deadlock per 5 ore ... – vehomzzz

17

Un blocco rientrante permette di scrivere un metodo M che mette un blocco sulla risorsa A e quindi chiamare M ricorsivamente o dal codice che contiene già un blocco su A.

Con un blocco non rientranti, sono necessarie 2 versioni di M, una che blocca e una che non lo fa e una logica aggiuntiva per chiamare quella giusta.

+1

La spiegazione pittorica sarebbe molto utile qui ... – Rachel

9

Il blocco di rientro è molto ben descritto in questo tutorial.

L'esempio nel tutorial è molto meno elaborato rispetto alla risposta relativa al passaggio di un grafico. Un blocco rientrante è utile in casi molto semplici.

Problemi correlati