¿Cuál es la diferencia entre un candado exclusivo y un candado compartido?

118

Según wikipedia,

Los bloqueos compartidos a veces se denominan "bloqueos de lectura" y los bloqueos exclusivos a veces se denominan "bloqueos de escritura".

¿Puede explicar el razonamiento detrás de los términos "compartido" y "exclusivo"?

Rosa Perrone
fuente
¿El bloqueo no exclusivo es otro nombre de bloqueo compartido?
Ramesh Papaganti

Respuestas:

418

Escribí esta respuesta porque pensé que sería una analogía divertida (y adecuada):

Piense en un objeto bloqueable como una pizarra (bloqueable) en un salón de clases que contiene un maestro (escritor) y muchos estudiantes (lectores).

Mientras un profesor escribe algo (candado exclusivo) en la pizarra:

  1. Nadie puede leerlo, porque todavía se está escribiendo y está bloqueando su vista => Si un objeto está bloqueado exclusivamente, no se pueden obtener bloqueos compartidos .

  2. Otros profesores tampoco se acercan y empiezan a escribir, o la pizarra se vuelve ilegible y confunde a los estudiantes => Si un objeto está bloqueado exclusivamente, no se pueden obtener otros bloqueos exclusivos .

Cuando los estudiantes están leyendo (candados compartidos) lo que hay en la pizarra:

  1. Todos pueden leer lo que contiene, juntos => Pueden coexistir múltiples cerraduras compartidas .

  2. La maestra espera a que terminen de leer antes de limpiar la pizarra para escribir más => Si ya existen uno o más candados compartidos, no se pueden obtener candados exclusivos .

ArjunShankar
fuente
2
muy buena explicacion. Sin embargo, el PO preguntó por el origen de las denominaciones "compartidas" y "exclusivas", no por una explicación de las térmicas per se.
serhio
¿Es este "Si ya existen uno o más bloqueos compartidos, no se pueden obtener bloqueos exclusivos"? ¿es verdad? interms de ReentrantReadWriteLock? Pensé que el bloqueo de escritura se puede obtener en cualquier momento, de lo contrario, la falta de escritura puede ocurrir debido a la lectura continua.
Kanagavelu Sugumar
1
@KanagaveluSugumar, sí, es verdad. Simplemente no puede obtener un bloqueo de escritura cuando otra entidad ya tiene un bloqueo de lectura en el mismo objeto. Ese es el objetivo de un bloqueo de lectura y escritura. Si sobrescribe algo mientras alguien más lo está leyendo, ¿qué leerían? No sé por qué eligió seleccionar un bloqueo de lectura-escritura "reentrante" específicamente, pero el reentrada significa que el propietario de un bloqueo de reentrante puede 'bloquearlo ()' nuevamente y todas las lock()llamadas posteriores después el primero regresará inmediatamente y con éxito. es decir, puede bloquear con éxito algo que ya posee.
ArjunShankar
2
También mencionas que "Pensé que el bloqueo de escritura se puede obtener en cualquier momento, de lo contrario, la falta de escritura puede ocurrir debido a la lectura continua"; esto simplemente no puede ser. No se puede obtener un bloqueo de escritura mientras alguna otra entidad ya tenga un bloqueo de lectura / escritura. Lo que puede suceder es que si varias entidades ya están esperando para bloquear un objeto, entonces writerse da preferencia a una espera sobre los lectores en espera cuando el bloqueo elige quién obtiene el bloqueo a continuación (cuando es desbloqueado por su propietario actual). Se trata de política .
ArjunShankar
¡Gracias! He elegido ReentrantReadWriteLock; ya que esa es la clase de implementación para ReadWriteLock en java. Entonces, ¿se ha levantado alguna bandera o se ha establecido más prioridad para decir que hay que esperar más nuevos hilos de lectura cuando el hilo de escritura comienza a esperar? Porque, ¿cómo evitar la falta de hilo de escritura debido a la solicitud de lectura continua?
Kanagavelu Sugumar
33

Es bastante sencillo. Los bloqueos de lectura también se conocen como bloqueos compartidos porque más de un proceso puede leer al mismo tiempo. El objetivo de un bloqueo de lectura es evitar que otro proceso adquiera un bloqueo de escritura. Por el contrario, un bloqueo de escritura inhibe todas las demás operaciones mientras se completa una operación de escritura, por lo que se describe como exclusiva.

Entonces, un bloqueo de lectura dice "puedes leer ahora, pero si quieres escribir tendrás que esperar", mientras que un bloqueo de escritura dice "tendrás que esperar".


Me doy cuenta de que estás investigando para respaldar tus estudios, pero no puedo resistir la tentación de dar una conferencia.

El uso inadecuado del bloqueo es una causa principal de problemas de rendimiento. El uso de un sistema de bloqueo que diferencia los bloqueos de lectura y escritura es un buen comienzo, pero un diseño cuidadoso a veces puede eliminar gran parte de la necesidad de bloquear. Por ejemplo, el estado de la sesión nunca debe mantenerse en una colección global por elemento de estado.

De hecho, he visto esto hecho. Es un diseño atroz, que provoca un cambio en una colección y un cambio en una colección por cada último cambio en el estado de la sesión, lo que implica un bloqueo de escritura prolongado. Los gastos generales eran agobiantes, reduciendo efectivamente el servidor a un comportamiento de un solo subproceso.

Simplemente agregar todo el estado de la sesión en una estructura fue una gran mejora. Los cambios en el estado de la sesión simplemente cambiaron los valores de los miembros de la estructura del estado de una sesión. Dado que ninguna otra sesión tuvo ocasión o oportunidad de hacer referencia directa al estado de una sesión, la única colección que se actualizó fue la lista de sesiones. Como resultado, el bloqueo fue completamente innecesario durante una sesión, solo al principio y al final, y el rendimiento aumentó en un factor de 3000.

El otro escenario de bloqueo común son los recursos compartidos entre subprocesos de una aplicación de usuario. La mayoría de los marcos modernos abordan esto usando mensajes en lugar de bloqueos; cuando realiza la "transición al hilo de la interfaz de usuario", en realidad está poniendo en cola un mensaje que contiene un puntero de función y algunos parámetros (o un delegado y un marco de pila según la implementación).

Peter Wone
fuente
6
  • Un bloqueo exclusivo o de escritura otorga a un proceso acceso exclusivo para escribir en la parte especificada del archivo. Mientras haya un bloqueo de escritura, ningún otro proceso puede bloquear esa parte del archivo.

  • Un bloqueo compartido o de lectura prohíbe que cualquier otro proceso solicite un bloqueo de escritura en la parte especificada del archivo. Sin embargo, otros procesos pueden solicitar bloqueos de lectura.

Más sobre eso: http://www.gnu.org/software/libc/manual/html_node/File-Locks.html

TOC
fuente
2

El mismo principio también en el lado de la base de datos. Según la documentación de Oracle

El modo de bloqueo exclusivo evita que se comparta el recurso asociado. Este modo de bloqueo se obtiene para modificar datos. La primera transacción para bloquear un recurso exclusivamente es la única transacción que puede alterar el recurso hasta que se libere el bloqueo exclusivo.

El modo de bloqueo compartido permite compartir el recurso asociado, según las operaciones involucradas. Varios usuarios que leen datos pueden compartir los datos, manteniendo bloqueos de uso compartido para evitar el acceso simultáneo de un escritor (que necesita un bloqueo exclusivo). Varias transacciones pueden
adquirir bloqueos de acciones en el mismo recurso.

usuario2155031
fuente