Questo dipende da come vengono implementati i blocchi. Se lo fai come nell'articolo di Wikipedia, vale a dire proteggere la sezione critica con un valore booleano per processo¹, sei sicuramente nei guai. Se un processo muore, non ripristina mai la sua bandiera, quindi l'altro processo scorre per sempre.
In pratica, puoi proteggere il tuo codice da molti modi di morire. Ad esempio, prendi questa implementazione in stile Java:
flag[1] = true;
turn = 1;
while ( flag[0] == true && turn == 1 ) { Thread.yield(); }
try {
// critical section
}
finally {
flag[1] = false;
}
Ciò assicurerà che il flag venga ripristinato qualunque cosa accada nella sezione critica, purché il sistema gestisca l'errore. In Java, questo vale anche per gli overflow di stack e heap. Quindi, a meno che il processo non svanisca letteralmente ( kill
², errore del processore, disconnessione della rete, ...), sei al sicuro. Si noti che la maggior parte dei software non critici fallisce in questi casi: come può gestire un errore che non è in esecuzione? - quindi deve essere accettato in molti casi. Se necessario, è possibile gestire le incoerenze al riavvio.
Se si utilizzano i blocchi appropriati a livello di lingua, il sistema di runtime può gestire i proprietari di blocchi che spariscono, ovvero rilasciare i blocchi con proprietari morti. Puoi simularlo tu stesso dando ad ogni processo un interruttore del morto che gli altri possono leggere, oppure controlla direttamente se il processo di possesso del blocco è ancora attivo (se il sistema lo supporta).
- Questo non si adatta bene, comunque.
- In Java, penso che
finalize
dovrebbe essere eseguito anche su kill
, ma questo non è garantito dalle specifiche. kill -9
è probabilmente una condanna a morte per qualsiasi soluzione che richiede al processo di morte di fare qualcosa.