Chiusure di rientro in C #

Il seguente codice determinerà un deadlock utilizzando C # su .NET?

class MyClass { private object lockObj = new object(); public void Foo() { lock(lockObj) { Bar(); } } public void Bar() { lock(lockObj) { // Do something } } } 

No, non finché si blocca sullo stesso object. Il codice ricorsivo ha già effettivamente il blocco e quindi può continuare senza ostacoli.

lock(object) {...} è una scorciatoia per usare la class Monitor . Come fa notare Marc , Monitor consente il re-entrancy , quindi i tentativi ripetuti di bloccare un object su cui il thread corrente ha già un blocco funzionerà perfettamente.

Se inizi a bloccare su oggetti diversi , è quando devi stare attento. Prestare particolare attenzione a:

  • Acquisisci sempre blocchi su un determinato numero di oggetti nella stessa sequenza.
  • Rilasciare sempre i blocchi nella sequenza inversa a come li acquisisci.

Se interrompi una di queste regole, ti verrà quasi garantito il problema di deadlock a un certo punto .

Ecco una buona pagina web che descrive la sincronizzazione dei thread in .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/

Inoltre, fissa il minor numero ansible di oggetti alla volta. Considerare l’applicazione di serrature a grana grossa laddove ansible. L’idea è che se puoi scrivere il tuo codice in modo tale che ci sia un grafico ad oggetti e puoi acquisire dei blocchi nella radice del grafico di quell’object, allora fallo. Ciò significa che hai un blocco su quell’object root e quindi non devi preoccuparti così tanto della sequenza in cui acquisisci / rilasci i blocchi.

(Un’ulteriore nota, il tuo esempio non è tecnicamente ricorsivo: per essere ricorsivo, Bar() dovrebbe chiamarsi, tipicamente come parte di un’iterazione).

Bene, Monitor permette di re-entrancy, quindi non puoi metterti in una situazione di stallo … quindi no: non dovrebbe farlo

Se un thread ha già un blocco, non si bloccherà. La struttura .Net garantisce questo. Devi solo assicurarti che due thread non tentino di acquisire gli stessi due blocchi fuori sequenza da qualunque percorso di codice.

Lo stesso thread può acquisire lo stesso blocco più volte, ma devi assicurarti di rilasciare il blocco lo stesso numero di volte che lo acquisisci. Naturalmente, finché si utilizza la parola chiave “lock” per ottenere ciò, avviene automaticamente.

No, questo codice non avrà blocchi morti. Se vuoi davvero creare un deadlock più semplice, è necessario almeno 2 risorse. Considera lo scenario del cane e dell’osso. 1. Un cane ha il pieno controllo su 1 osso, quindi ogni altro cane deve aspettare. 2. 2 cani con 2 ossa sono minimi richiesti per creare un punto morto quando bloccano le loro ossa rispettivamente e cercano anche altre ossa.

.. così via, e così via, cani e ossa, e causano più sofisticate situazioni di stallo.