Esto depende de cómo se implementen los bloqueos. Si lo hace como en el artículo de Wikipedia, es decir, protegiendo la sección crítica con un booleano por proceso¹, ciertamente está en problemas. Si un proceso muere, nunca restablece su bandera, por lo que el otro proceso se repite para siempre.
En la práctica, puede proteger su código contra muchas formas de morir. Por ejemplo, tome esta implementación de estilo Java:
flag[1] = true;
turn = 1;
while ( flag[0] == true && turn == 1 ) { Thread.yield(); }
try {
// critical section
}
finally {
flag[1] = false;
}
Esto asegurará que el indicador se restablezca pase lo que pase en la sección crítica, siempre y cuando el sistema esté manejando el error. En Java, eso es cierto incluso para desbordamientos de pila y montón. Entonces, a menos que el proceso desaparezca literalmente ( kill
², falla del procesador, desconexión de la red, ...) está a salvo. Tenga en cuenta que la mayoría del software no crítico falla en estos casos: ¿cómo puede manejar un error si no se está ejecutando? - por lo que tiene que ser aceptado en muchos casos. Puede manejar inconsistencias al reiniciar si es necesario.
Si usa los bloqueos adecuados de nivel de idioma, el sistema de tiempo de ejecución puede manejar los propietarios de bloqueos que desaparecen, es decir, liberar los bloqueos con los propietarios muertos. Puede simular esto usted mismo dando a cada proceso un interruptor de hombre muerto que los demás puedan leer, o verificar directamente si el proceso de posesión del bloqueo aún está activo (si el sistema lo admite).
- Eso no escala bien, de todos modos.
- En Java, creo que
finalize
debería ejecutarse incluso en kill
, pero esto no está garantizado por la especificación. kill -9
es probablemente una sentencia de muerte para cualquier solución que requiera que el proceso de morir haga algo.