2009-12-23 8 views
21

Me enteré de que debía desbloquear el orden inverso para bloquear el pedido. Por ejemplo.¿Podría explicar el orden de bloqueo?

A.lock(); 
B.lock(); 
B.unlock(); 
A.unlock(); 

Pero, ¿qué ocurre si lo hiciera así:

A.lock(); 
B.lock(); 
A.unlock(); 
B.unlock(); 

Trato de hacer un escenario de estancamiento, pero si Siempre bloquear una anterior entonces B, entonces no sé cómo un punto muerto ¿Me ayudarías?

+0

¿Estás hablando de un caso en el que hay procesos múltiples que tienen bloqueos o solo estás tratando con un solo proceso? –

+0

procesos múltiples, por supuesto. –

+4

No "por supuesto", ¿por qué procesos múltiples? Se aplica igual de bien a los hilos dentro de un solo proceso. – djna

Respuesta

19

El bloqueo de pedidos solo significa que puede evitar interbloqueos obteniendo bloqueos en un orden fijo, y no obtiene bloqueos nuevamente después de comenzar a desbloquear.

No creo que el orden de los desbloqueos hace ninguna diferencia aquí (de hecho, debería ser beneficioso para liberar un bloqueo tan pronto como sea posible, incluso si fuera de servicio)

9

Su ejemplo no va a punto muerto consigo mismo alguna vez. Desbloquear en orden inverso no es importante, se bloquea en un orden consistente. Esto se bloqueará, aunque los desbloqueos están en orden inverso

Thread 1 

A.lock(); 
B.lock(); 
B.unlock(); 
A.unlock(); 

Thread 2 

B.lock(); 
A.lock(); 
A.unlock(); 
B.unlock(); 
2

No creo que se produzca un punto muerto aquí. El concepto general de interbloqueo es que un subproceso espera algún recurso bloqueado por otro subproceso, mientras que otro subproceso necesita recursos bloqueados por el primer subproceso para finalizar y liberar primero el recurso necesario.

Further reading

1

El orden de desbloqueo no afectará a la forma propensa su sistema está a un punto muerto, sin embargo hay una razones para pensar acerca de la orden de desbloqueo:

Con el fin de evitar los puntos muertos que necesidad maquillaje Asegúrese de que su bloqueo/desbloqueo esté sincronizado, ya que nunca se perderá un desbloqueo. Como enfoque estilístico, al contar conspicuamente con bloques de código que son responsables de un bloqueo particular, es mucho más fácil identificar visualmente que los bloqueos y desbloqueos están sincronizados. El efecto final es que el código claramente correcto probablemente tomará y liberará los bloqueos como usted describe.

32

En el caso simple dado, no es necesario desbloquear en el orden inverso para evitar un interbloqueo.

Sin embargo, como el código se vuelve más complicado, desbloquearlo en el orden inverso lo ayuda a mantener un orden de bloqueo correcto.

considerar:

A.lock(); 
B.lock(); 
Foo(); 
A.unlock(); 
Bar(); 
B.unlock(); 

If Bar() intenta readquirir A, que ha roto con eficacia su pedido de bloqueo. Está presionando B y luego tratando de obtener A. Ahora es puede punto muerto.

Si desbloquea en el estilo orden inverso (que es muy natural si se utiliza RAII):

A.lock(); 
B.lock(); 
Foo(); 
B.unlock(); 
Bar(); 
A.unlock(); 

entonces no importa si Bar() intentos para tomar una cerradura, como se conservará pedido de bloqueo .

+1

Esta es _la_ respuesta correcta IMO: si acepta la regla de tomar bloqueos en el mismo orden en su sistema en diferentes niveles (funciones internas, etc.) y don lanzamiento en el orden inverso, el escenario de la respuesta de Adrián conduce a una posibilidad de bloqueo. Me gustaría que este "** puede un punto muerto **" fuera un poco más visible por debajo del argumento del "buen estilo" (que también estoy totalmente de acuerdo). – starikoff

+0

No solo es esta la respuesta correcta, sino que todas las respuestas que afirman que el orden de desbloqueo es irrelevante para el punto muerto son erróneas. –

+0

Bueno, ese problema solo ocurre si vuelve a adquirir bloqueos que ha liberado anteriormente (sin antes también liberar los bloqueos "posteriores"). Mi respuesta supuestamente incorrecta define el orden de bloqueo como "obtener bloqueos en un orden fijo y no obtener bloqueos nuevamente después de que comiences a desbloquear". – Thilo

0

Y para Java, el desbloqueo es en el orden inverso si synchronized palabra clave se utiliza para el bloqueo. No hay forma de desbloquear en un orden diferente para usar la palabra clave synchronized.

synchronized(a) { 
    synchronized(b) { 
    // statements 
    } 
} 
+2

Quiero expresar que no estoy de acuerdo con los votos a favor en esta respuesta. Aunque no es el más elaborado sobre esta cuestión, sí muestra otra perspectiva, quizás ayudando a comprender el asunto. –

0
 > lock(B)                                                 
     > ---------- lock(C) 
     > ---------- lock(B) >>>> would block here 
     > ---------- release(B) 
     > ---------- release(C) 
     > lock(C)  >>>>>> would block here 
     > release(B) 
     > release(C) 

Su respuesta es grande, aquí es otra situación se puede producir un punto muerto si no ordenada de desbloqueo & se lleva a cabo. Una palabra, Versión desordenada & bloqueo rompe la suposición que utilizamos para diseñar nuestra zona de administración de recursos compartidos y crítica.

Cuestiones relacionadas