2009-11-30 9 views
11

el módulo de subprocesamiento en Python proporciona dos tipos de bloqueos: un bloqueo común y un bloqueo de reentrada. Me parece que si necesito un candado, siempre debería preferir el RLock sobre el candado; principalmente para evitar situaciones de estancamiento.¿RLock es un valor predeterminado por bloqueo?

Además de eso, veo dos puntos, cuando a preferir un bloqueo sobre un RLock:

  • RLock tiene una estructura interna más complicado y por lo tanto pueden tener un peor rendimiento.
  • Por alguna razón, quiero evitar que un hilo se repita a través del bloqueo.

¿Mi razonamiento es correcto? ¿Puedes señalar otros aspectos?

+1

# 2 es poco probable que sea una buena razón; el único caso en el que no es un punto muerto garantizado es si la recursión adquiere no bloqueo y tiene un curso de acción razonable cuando no puede verificar que contiene el bloqueo. Y el # 1 no se aplica en Python 3.2+. Una razón legítima para preferir 'Bloquear' es cuando el bloqueo debe liberarse en un hilo diferente al que lo adquirió. – ShadowRanger

Respuesta

10

dos puntos:

  • En las versiones de Python oficialmente lanzadas (2.4, 2.5 ... hasta 3.1), un RLock es mucho más lento que un bloqueo, ya que los bloqueos se implementan en C y RLocks en Python (esto va a cambiar en 3.2)
  • a Lock puede ser liberado de cualquier hilo (no necesariamente el hilo que adquirir() d ella), mientras que un RLock tiene que ser liberada por el mismo hilo que adquirió

En pocas palabras, sugiero que solo use un RLock si coincide con la semántica que tiene buscando, de lo contrario, se adhieren a Bloqueos de forma predeterminada.

+1

Dicho esto, 'RLock's puede simplificar el código. Si hay dos métodos que ambos necesitan mantener el bloqueo, y uno llama al otro, la arquitectura para 'Bloquear' simple requiere que se divida el método" interno "en una utilidad desbloqueada, con el nombre público bloqueando y llamando al método interno, mientras que el método "externo" llama directamente a la utilidad desbloqueada. Y debe hacer esto cada vez que participe en la reutilización de código de este formulario. Además, 'RLock' elimina el riesgo de bloquear silenciosamente un hilo y desbloquearlo en otro (impone el bloqueo y desbloqueo del mismo hilo); evita errores en el caso común. – ShadowRanger

+0

Teniendo en cuenta el rendimiento alcanzado en 3.1 y en las versiones inferiores, generalmente podría recomendar 'Lock' por razones prácticas, pero en 3.2+,' RLock' es menos complicado de usar, evita errores comunes y es igual de eficiente; realmente usas 'Lock' solo cuando necesitas funciones específicas' Lock' (por ejemplo, cross-thread acquire/release, usándolo como una barrera para los camareros; waiter crea 'Lock',' acquire's una vez, agrega a una lista de esperar bloqueos, 'adquirir's nuevamente, bloqueo; alertador luego' liberar's para dejar que el 'camarero' continúe (por supuesto, solo estoy describiendo qué' Condición' hace por ti, así que no lo hagas tú mismo) . – ShadowRanger

3

Normalmente, debe estructurar su código de forma tal que nunca necesite bloquear de forma recursiva el funcionamiento normal (básicamente, lo obliga a usar bloqueos estrechamente alrededor de las estructuras de datos protegidas que protegen). Por lo tanto, desea capturar un bloqueo recursivo anómalo.

+0

Su respuesta implica que [el ejemplo] (http://effbot.org/zone/thread-synchronization.htm#re-entrant-locks-rlock) usado para motivar a 'RLock' en primer lugar debe ser reescrito usando cerraduras más cerradas, en cuyo punto no necesitará 'RLock'. ¿Estarías de acuerdo? Y si es así, ¿cuál es un buen ejemplo que motiva la necesidad de 'RLock'? – max

Cuestiones relacionadas