¿Qué es un punto muerto?

159

Al escribir aplicaciones multiproceso, uno de los problemas más comunes experimentados son los puntos muertos.

Mis preguntas a la comunidad son:

  1. ¿Qué es un punto muerto?

  2. ¿Cómo los detectas?

  3. ¿Los manejas?

  4. Y finalmente, ¿cómo evitas que ocurran?

bmurphy1976
fuente

Respuestas:

207

Se produce un bloqueo cuando varios procesos intentan acceder al mismo recurso al mismo tiempo.

Un proceso pierde y debe esperar a que termine el otro.

Se produce un punto muerto cuando el proceso de espera todavía se está quedando con otro recurso que el primero necesita antes de que pueda finalizar.

Entonces, un ejemplo:

Los recursos A y B son utilizados por el proceso X y el proceso Y

  • X comienza a usar A.
  • X e Y intentan comenzar a usar B
  • Y 'gana' y obtiene B primero
  • ahora Y necesita usar A
  • A está bloqueado por X, que está esperando a Y

La mejor manera de evitar puntos muertos es evitar que los procesos se crucen de esta manera. Reduzca la necesidad de bloquear todo lo que pueda.

En las bases de datos, evite realizar muchos cambios en diferentes tablas en una sola transacción, evite los desencadenantes y cambie a lecturas optimistas / sucias / nolock tanto como sea posible.

Keith
fuente
9
Estoy usando el proceso aquí como una generalización, no específicamente un proceso del sistema operativo. Estos podrían ser subprocesos, pero también podrían ser aplicaciones completamente diferentes o conexiones de bases de datos. El patrón es el mismo.
Keith
1
Hola, dado este escenario: el subproceso A bloquea el recurso A y tiene un proceso largo. Hilo B a la espera de bloquear el recurso A. Uso de tiempo de CPU: 20%, ¿puede considerarlo una situación de punto muerto?
rickyProgrammer
2
@rickyProgrammer no, eso es solo una espera de bloqueo regular, aunque la diferencia es un poco académica. B esperando lento A es una cerradura, B esperando A esperando B es un punto muerto.
Keith
Así estancamiento es más de dos procesos con recursos bloqueados en espera de esos recursos para ser lanzado ..
rickyProgrammer
2
@rickyProgrammer es un bloqueo que no se liberará, sin importar cuánto tiempo espere, debido a la cola circular.
Keith
126

Permítanme explicar un ejemplo del mundo real (no realmente real) para una situación de punto muerto de las películas de crimen. Imagine que un criminal tiene un rehén y, contra eso, un policía también tiene un rehén que es amigo del criminal. En este caso, el criminal no va a dejar ir al rehén si el policía no deja que su amigo lo deje ir. Además, el policía no va a dejar ir al amigo del criminal, a menos que el criminal libere al rehén. Esta es una situación interminable y poco confiable, porque ambas partes están insistiendo en el primer paso el uno del otro.

Escena criminal y policial

ingrese la descripción de la imagen aquí

Entonces, simplemente, cuando dos hilos necesitan dos recursos diferentes y cada uno de ellos tiene el bloqueo del recurso que el otro necesita, es un punto muerto.

Otra explicación de alto nivel de Deadlock: Broken Hearts

Estás saliendo con una chica y un día después de una discusión, ambas partes están desconsoladas y esperando una llamada de " Lo siento, perdí y te perdí" . En esta situación, ambas partes quieren comunicarse entre sí si y solo si una de ellas recibe una llamada de disculpa de la otra. Debido a que ninguno de los dos va a comenzar la comunicación y esperará en un estado pasivo, ambos esperarán a que el otro inicie la comunicación que termina en una situación de punto muerto.

Levent Divilioglu
fuente
¿Deberían los hilos pertenecer a diferentes procesos ?, ¿los hilos que pertenecen al mismo proceso también pueden causar un punto muerto?
lordvcs
1
@diabolicfreak No importa si los hilos pertenecen al mismo proceso o no.
Sam Malayek
2
Otro ejemplo de la vida real podría ser que cuatro autos lleguen al cruce de dos caminos iguales en cuatro direcciones simultáneamente. Todos deben dar paso a un automóvil desde el lado derecho, para que nadie pueda continuar.
LoBo
35

Los puntos muertos solo ocurrirán cuando tengas dos o más bloqueos que se puedan adquirir al mismo tiempo y se agarren en un orden diferente.

Las formas de evitar tener puntos muertos son:

  • evitar tener cerraduras (si es posible),
  • evitar tener más de una cerradura
  • Siempre tome las cerraduras en el mismo orden.
Mats Fredriksson
fuente
El tercer punto para evitar un punto muerto (siempre tome los bloqueos en el mismo orden) es vital, lo cual es bastante fácil de olvidar en la práctica de la codificación.
Qiang Xu
20

Para definir un punto muerto, primero definiría el proceso.

Proceso : Como sabemos, el proceso no es más que una programejecución.

Recurso : Para ejecutar un proceso de programa se necesitan algunos recursos. Las categorías de recursos pueden incluir memoria, impresoras, CPU, archivos abiertos, unidades de cinta, CD-ROM, etc.

Punto muerto : el punto muerto es una situación o condición en la que dos o más procesos retienen algunos recursos e intentan adquirir algunos más, y no pueden liberarlos hasta que terminen su ejecución.

Condición o situación de punto muerto

ingrese la descripción de la imagen aquí

En el diagrama anterior hay dos procesos P1 y p2 y hay dos recursos R1 y R2 .

El recurso R1 se asigna al proceso P1 y el recurso R2 se asigna al proceso p2 . Para completar la ejecución del proceso, P1 necesita el recurso R2 , por lo que P1 solicita R2 , pero R2 ya está asignado a P2 .

Del mismo modo, el proceso P2 para completar su ejecución necesita R1 , pero R1 ya está asignado a P1 .

ambos procesos no pueden liberar su recurso hasta que completen su ejecución y, a menos que lo hagan. Así que ambos esperan otros recursos y esperarán para siempre. Entonces esta es una condición de DEADLOCK .

Para que se produzca un punto muerto, deben cumplirse cuatro condiciones.

  1. Exclusión mutua : cada recurso está actualmente asignado a exactamente un proceso o está disponible. (Dos procesos no pueden controlar simultáneamente el mismo recurso o estar en su sección crítica).
  2. Retener y esperar : los procesos que actualmente tienen recursos pueden solicitar nuevos recursos.
  3. Sin preferencia : una vez que un proceso retiene un recurso, otro proceso o el núcleo no puede quitarlo.
  4. Espera circular : cada proceso está esperando obtener un recurso retenido por otro proceso.

y todas estas condiciones se cumplen en el diagrama anterior.

Varun
fuente
8

Un punto muerto ocurre cuando un hilo está esperando algo que nunca ocurre.

Por lo general, ocurre cuando un subproceso está esperando un mutex o semáforo que nunca fue liberado por el propietario anterior.

También ocurre con frecuencia cuando tienes una situación que involucra dos hilos y dos bloqueos como este:

Thread 1               Thread 2

Lock1->Lock();         Lock2->Lock();
WaitForLock2();        WaitForLock1();   <-- Oops!

Generalmente los detecta porque las cosas que espera que sucedan nunca suceden, o la aplicación se bloquea por completo.

17 de 26
fuente
Un punto muerto ocurre cuando un hilo está esperando algo que no puede ocurrir.
Marqués de Lorne
4

Puedes echar un vistazo a estos maravillosos artículos , en la sección Punto muerto . Está en C # pero la idea sigue siendo la misma para otra plataforma. Cito aquí para facilitar la lectura

Un punto muerto ocurre cuando dos subprocesos cada uno espera un recurso en poder del otro, por lo que ninguno puede continuar. La forma más fácil de ilustrar esto es con dos bloqueos:

object locker1 = new object();
object locker2 = new object();

new Thread (() => {
                    lock (locker1)
                    {
                      Thread.Sleep (1000);
                      lock (locker2);      // Deadlock
                    }
                  }).Start();
lock (locker2)
{
  Thread.Sleep (1000);
  lock (locker1);                          // Deadlock
}
onmyway133
fuente
4

El punto muerto es un problema común en los problemas de multiprocesamiento / multiprogramación en el sistema operativo. Digamos que hay dos procesos P1, P2 y dos recursos compartibles globalmente R1, R2 y en la sección crítica ambos recursos necesitan ser accedidos

Inicialmente, el sistema operativo asigna R1 para procesar P1 y R2 para procesar P2. Como ambos procesos se ejecutan simultáneamente, pueden comenzar a ejecutar su código, pero el PROBLEMA surge cuando un proceso llega a la sección crítica. Por lo tanto, el proceso R1 esperará a que el proceso P2 libere R2 y viceversa ... Entonces esperarán para siempre (CONDICIÓN DE DESBLOQUEO).

Una pequeña analogía ...

Tu madre (SO),
tú (P1),
tu hermano (P2),
manzana (R1),
cuchillo (R2),
sección crítica (cortar manzana con cuchillo).

Tu madre te da la manzana y el cuchillo a tu hermano al principio.
Ambos están contentos y jugando (ejecutando sus códigos).
Cualquiera de ustedes quiere cortar la manzana (sección crítica) en algún momento.
No quieres darle la manzana a tu hermano.
Tu hermano no quiere darte el cuchillo.
Así que ambos esperarán mucho, mucho tiempo :)

Rohit Singh
fuente
2

El punto muerto ocurre cuando dos hilos adquieren bloqueos que impiden que cualquiera de ellos progrese. La mejor manera de evitarlos es con un desarrollo cuidadoso. Muchos sistemas integrados protegen contra ellos mediante el uso de un temporizador de vigilancia (un temporizador que restablece el sistema cada vez que se cuelga durante un cierto período de tiempo).

Joseph Sturtevant
fuente
2

Un punto muerto se produce cuando hay una cadena circular de subprocesos o procesos que contienen un recurso bloqueado y tratan de bloquear un recurso retenido por el siguiente elemento de la cadena. Por ejemplo, dos hilos que sostienen respectivamente el bloqueo A y el bloqueo B, y ambos intentan adquirir el otro bloqueo.

Marqués de Lorne
fuente
Yo te voto a ti. Su respuesta es más concisa que la anterior porque hacen que el punto muerto confuso suceda por proceso o hilo. Alguien dice proceso, alguien dice hilo :)
hainguyen
1

Un programa clásico y muy simple para comprender la situación de Deadlock : -

public class Lazy {

    private static boolean initialized = false;

    static {
        Thread t = new Thread(new Runnable() {
            public void run() {
                initialized = true;
            }
        });

        t.start();

        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println(initialized);
    }
}

Cuando el hilo principal invoca Lazy.main, comprueba si la clase Lazy se ha inicializado y comienza a inicializar la clase. El subproceso principal ahora se establece inicializado en falso, crea e inicia un subproceso en segundo plano cuyo método de ejecución establece inicializado en verdadero y espera a que se complete el subproceso en segundo plano.

Esta vez, la clase está siendo inicializada por otro hilo. En estas circunstancias, el subproceso actual, que es el subproceso de fondo, espera en el objeto Clase hasta que se completa la inicialización. Desafortunadamente, el hilo que está haciendo la inicialización, el hilo principal, está esperando que se complete el hilo de fondo. Debido a que los dos subprocesos ahora se están esperando, el programa está DESBLOQUEADO.

Vivek Pratap Singh
fuente
0

Un punto muerto es un estado de un sistema en el que ningún proceso / subproceso único es capaz de ejecutar una acción. Como lo mencionaron otros, un punto muerto suele ser el resultado de una situación en la que cada proceso / subproceso desea adquirir un bloqueo a un recurso que ya está bloqueado por otro (o incluso el mismo) proceso / subproceso.

Existen varios métodos para encontrarlos y evitarlos. Uno está pensando mucho y / o probando muchas cosas. Sin embargo, lidiar con el paralelismo es notoriamente difícil y la mayoría (si no todas) las personas no podrán evitar por completo los problemas.

Algunos métodos más formales pueden ser útiles si se toma en serio el tratamiento de este tipo de problemas. El método más práctico que conozco es utilizar el enfoque teórico del proceso. Aquí puede modelar su sistema en algún lenguaje de proceso (por ejemplo, CCS, CSP, ACP, mCRL2, LOTOS) y utilizar las herramientas disponibles para (modelar) verificar los puntos muertos (y quizás también algunas otras propiedades). Ejemplos de herramientas para usar son FDR, mCRL2, CADP y Uppaal. Algunas almas valientes podrían incluso demostrar que sus sistemas están libres de puntos muertos mediante el uso de métodos puramente simbólicos (prueba de teoremas; busque Owicki-Gries).

Sin embargo, estos métodos formales generalmente requieren cierto esfuerzo (por ejemplo, aprender los conceptos básicos de la teoría de procesos). Pero supongo que eso es simplemente una consecuencia del hecho de que estos problemas son difíciles.

mweerden
fuente
0

El punto muerto es una situación que ocurre cuando hay menos cantidad de recursos disponibles según lo solicitado por el proceso diferente. Significa que cuando el número de recursos disponibles es menor de lo solicitado por el usuario, en ese momento el proceso pasa a la espera. Algunas veces la espera aumenta más y no hay ninguna posibilidad de verificar el problema de falta de recursos. Esta situación se conoce como punto muerto. En realidad, el punto muerto es un problema importante para nosotros y solo ocurre en el sistema operativo multitarea.

puja bharti
fuente
0

Por encima algunas explicaciones son agradables. Espero que esto también sea útil: https://ora-data.blogspot.in/2017/04/deadlock-in-oracle.html

En una base de datos, cuando una sesión (p. Ej., Ora) quiere un recurso retenido por otra sesión (p. Ej., Datos), pero esa sesión (datos) también quiere un recurso retenido por la primera sesión (ora). También puede haber más de 2 sesiones involucradas, pero la idea será la misma. En realidad, los puntos muertos impiden que algunas transacciones continúen funcionando. Por ejemplo: supongamos que ORA-DATA mantiene el bloqueo A y solicita el bloqueo B Y el SKU mantiene el bloqueo B y solicita el bloqueo A.

Gracias,

Sapna
fuente
0

El punto muerto ocurre cuando un hilo está esperando que otro hilo termine y viceversa.

¿Como evitar?
- Evite bloqueos anidados
- Evite bloqueos innecesarios
- Use hilo unirse ()

¿Cómo lo detectas?
ejecuta este comando en cmd:

jcmd $PID Thread.print

referencia : geeksforgeeks

Arun Raaj
fuente
0

Los puntos muertos no solo ocurren con bloqueos, aunque esa es la causa más frecuente. En C ++, puede crear un punto muerto con dos hilos y sin bloqueos simplemente haciendo que cada llamada de hilo se una () en el objeto std :: thread para el otro.

Raghav Navada
fuente
0

Control de concurrencia basado en bloqueo

El uso del bloqueo para controlar el acceso a los recursos compartidos es propenso a puntos muertos, y el planificador de transacciones por sí solo no puede evitar que ocurran.

Por ejemplo, los sistemas de bases de datos relacionales usan varios bloqueos para garantizar las propiedades ACID de la transacción .

No importa qué sistema de base de datos relacional esté utilizando, siempre se adquirirán bloqueos al modificar (por ejemplo, UPDATEo DELETE) un determinado registro de tabla. Sin bloquear una fila que fue modificada por una transacción actualmente en ejecución, Atomicity se vería comprometida .

¿Qué es un punto muerto?

Como expliqué en este artículo , se produce un punto muerto cuando dos transacciones simultáneas no pueden avanzar porque cada una espera que la otra libere un bloqueo, como se ilustra en el siguiente diagrama.

ingrese la descripción de la imagen aquí

Debido a que ambas transacciones están en la fase de adquisición de bloqueo, ninguna libera un bloqueo antes de adquirir la siguiente.

Recuperándose de una situación de punto muerto

Si está utilizando un algoritmo de Control de concurrencia que se basa en bloqueos, siempre existe el riesgo de ejecutarse en una situación de bloqueo. Los puntos muertos pueden ocurrir en cualquier entorno de concurrencia, no solo en un sistema de base de datos.

Por ejemplo, un programa de subprocesos múltiples puede llegar a un punto muerto si dos o más subprocesos están esperando bloqueos que se adquirieron previamente para que ningún subproceso pueda avanzar. Si esto sucede en una aplicación Java, la JVM no puede forzar a un Thread a detener su ejecución y liberar sus bloqueos.

Incluso si la Threadclase expone un stopmétodo, ese método ha quedado en desuso desde Java 1.1 porque puede hacer que los objetos se dejen en un estado inconsistente después de que se detiene un subproceso. En cambio, Java define un interruptmétodo, que actúa como una pista, ya que un hilo que se interrumpe puede simplemente ignorar la interrupción y continuar su ejecución.

Por esta razón, una aplicación Java no puede recuperarse de una situación de punto muerto, y es responsabilidad del desarrollador de la aplicación ordenar las solicitudes de adquisición de bloqueo de tal manera que nunca se produzcan puntos muertos.

Sin embargo, un sistema de base de datos no puede imponer una orden de adquisición de bloqueo dado, ya que es imposible prever qué otros bloqueos querrá adquirir una determinada transacción. Preservar el orden de bloqueo se convierte en responsabilidad de la capa de acceso a datos, y la base de datos solo puede ayudar a recuperarse de una situación de punto muerto.

El motor de la base de datos ejecuta un proceso separado que escanea el gráfico de conflicto actual en busca de ciclos de bloqueo-espera (que son causados ​​por puntos muertos). Cuando se detecta un ciclo, el motor de la base de datos selecciona una transacción y la cancela, haciendo que se liberen sus bloqueos, para que la otra transacción pueda progresar.

A diferencia de la JVM, una transacción de base de datos está diseñada como una unidad atómica de trabajo. Por lo tanto, una reversión deja la base de datos en un estado consistente.

Para obtener más detalles sobre este tema, consulte también este artículo .

Vlad Mihalcea
fuente
-2

Mutex en esencia es un candado, que proporciona acceso protegido a recursos compartidos. En Linux, el tipo de datos de mutex de subproceso es pthread_mutex_t. Antes de usar, inicialízalo.

Para acceder a los recursos compartidos, debe bloquear el mutex. Si el mutex ya está en la cerradura, la llamada bloqueará el hilo hasta que se desbloquee el mutex. Al finalizar la visita a los recursos compartidos, debe desbloquearlos.

En general, hay algunos principios básicos no escritos:

  • Obtenga el bloqueo antes de usar los recursos compartidos.

  • Sosteniendo la cerradura el menor tiempo posible.

  • Libere el bloqueo si el hilo devuelve un error.

Marcus Thornton
fuente
3
Esto describe un bloqueo, no un punto muerto.
Marqués de Lorne