2009-11-30 12 views
11

il modulo di threading in Python fornisce due tipi di blocchi: un blocco comune e un blocco rientrante. Mi sembra che, se ho bisogno di un lucchetto, preferirei sempre RLock over the Lock; principalmente per prevenire situazioni di deadlock.RLock è un valore predefinito rispetto al blocco?

Oltre a questo, vedo due punti, quando a preferire un blocco su un RLock:

  • RLock ha una più complessa struttura interna e possono pertanto avere prestazioni peggiori.
  • A causa di qualche motivo, voglio impedire una ricorrenza del thread attraverso il blocco.

Il mio ragionamento è corretto? Puoi indicare altri aspetti?

+1

# 2 è improbabile che sia una buona ragione; l'unico caso in cui non è un deadlock garantito è se la ricorsione acquisisce non-blocking e ha un ragionevole corso d'azione quando non può verificare che detenga il lock. E # 1 non si applica su Python 3.2+. Un motivo legittimo per preferire 'Lock' è quando il lock deve essere rilasciato in un thread diverso da quello che lo ha acquisito. – ShadowRanger

risposta

10

due punti:

  • Nelle versioni di Python ufficialmente rilasciato (2.4, 2.5 ... fino a 3.1), un RLock è molto più lento di un blocco, perché i blocchi sono implementate in C e RLocks in Python (questo cambierà in 3.2)
  • un blocco può essere rilasciato da qualsiasi thread (non necessariamente il filo che acquisiscono() d), mentre un RLock deve essere rilasciato dallo stesso filo che acquisito

In conclusione, suggerirei di usare solo un RLock se corrisponde alla semantica che sei in cerca di, altrimenti attenersi a Locks per impostazione predefinita.

+1

Detto questo, 'RLock's può semplificare il codice. Se ci sono due metodi che richiedono entrambi di tenere il blocco, e uno chiama l'altro, l'architettura per semplice 'Lock' richiede di dividere il metodo" interno "in un'utilità sbloccata, con il nome pubblico che blocca e chiama il metodo interno, mentre il metodo "esterno" chiama direttamente l'utilità sbloccata. E devi farlo ogni volta che ti impegni a riutilizzare il codice di questo modulo. Inoltre, 'RLock' rimuove il rischio di bloccare silenziosamente in un thread e di sbloccarlo in un altro (impone il blocco e lo sblocco dallo stesso thread); previene errori nel caso comune. – ShadowRanger

+0

Dato il successo delle prestazioni in 3.1 e sotto, ho potuto vedere generalmente raccomandare 'Lock' lì per ragioni pratiche, ma in 3.2+,' RLock' è meno complicato da usare, previene errori comuni ed è altrettanto efficiente; usi veramente 'Lock' solo quando hai bisogno delle funzionalità specifiche di' Lock' (es. acquisizione/rilascio cross-thread, usandolo come una barriera per i camerieri; il cameriere crea 'Lock',' acquisisce una volta, aggiunge a una lista di attendi i blocchi, 'acquisisci' s di nuovo, blocca, poi rilascia 'release's per permettere al' cameriere 'di continuare (naturalmente, sto solo descrivendo ciò che 'Condition' fa per te, quindi non farlo tu stesso) . – ShadowRanger

3

Normalmente si dovrebbe strutturare il codice in modo tale da non dover mai ricorrere in modo ricorsivo durante il normale funzionamento (in pratica si costringe a utilizzare i blocchi strettamente attorno alle strutture protette che stanno proteggendo). Pertanto si desidera rilevare un blocco ricorsivo anomalo.

+0

La tua risposta implica che [l'esempio] (http://effbot.org/zone/thread-synchronization.htm#re-entrant-locks-rlock) utilizzato per motivare 'RLock' in primo luogo dovrebbe essere riscritto usando serrature più strette, a quel punto non sarà necessario 'RLock'. Sei d'accordo? E se sì, quale è un buon esempio che motiva la necessità di 'RLock'? – max

Problemi correlati