Deadlock Definition deadlock (baglås) er en tilstand som en mængde af processer kan være i en mængde processer er i deadlock hvis alle processerne står i følgende situation: processen venter på en hændelse som kun en anden af processerne kan udføre. Typisk: "vente" = processen er blokeret fordi der ventes på adgang til en ressource "hændelse" = en anden proces frigiver ressourcen.
Race condition class Fork { boolean available; Fork() {available = true}; void take_fork() { if (available) available = false; } void put_fork() { available = true; } To processer kan tro de begge har taget gaflen, hvis begge udfører testen før tildelingen
Race condition undgået med semaforer void take_fork() { down(sem); if (available) available = false; up(sem); } Kun 1 proces ad gangen får lov at udføre koden i den kritiske sektion
Semafor-operationer: down og up skal være atomiske // Forenklet implementation i C af semaforer // Semaforen er repræsenteret ved et heltal. down(int *sem) { if (*sem=0) {SLEEP UNTIL WAKEUP}; *sem = *sem - 1; } up(int *sem){ *sem = *sem + 1; {WAKEUP ONE SLEEPING PROCESS}; } ? sleep *Sem-- *sem++ wakeup
Deadlock: graf-notation R1R2 P1P2 Proces P1 "besidder" ressource R1 Proces P2 venter på ressource R2. (Proces P2 er blokeret)
Cirkulær sti svarer til deadlock R1R2 P1P2 Grafen er et øjebliksbillede af programudførelsen
Deadlock i distribuerede systemer Samme grundprincipper. Mange fejlmuligheder som der skal tages højde for. Mere komplekse systemer. Transaktioner i database-systemer, der overholder ACID-kriterierne, og som kan aborteres, giver mulighed for at løse en deadlock. Særlige problemer ved: - centraliseret deadlock-detektion - synkronisering vhja. tidsstempler
Centraliseret deadlock-detektion - risiko for "falsk deadlock" S TR AC B R frigives af B, men besked forsinkes Efter frigivelsen af R, venter B på T (besked forsinkes ikke)
Ressource-grafer: forenklet notation R P1P2 P1P2
Distribueret deadlock-detektion Besked (0,0,1) sendes fra proces 0 til proces 1. Betydning: (Blokeret proces, Afsenderproces, Modtagerproces) (0,5,7)
Wait-die P1P2 Hvis P1 er yngre and P2, slås P1 ihjel.
Filosof-fest PartyFilosof Gaffel
Beskyttelse af kritisk sektion med synchronized class Fork { boolean available; Fork() {available = true}; synchronized void take_fork() { if (available) available = false; } synchronized void put_fork() { available = true; } Synchronized sætter lås på objektet (fork- instansen): ingen andre må udføre en synchronized metode i objektet.
wait() og notify() class Fork { boolean available; Fork() {available = true}; synchronized void take_fork() { while (! available) {wait()} available = false; } void put_fork() { available = true; notify(); } Den tråd, der har kaldt wait() blokeres, og låsen på Fork- objektet fjernes. notify() gen-aktiverer en tråd, der er blokeret (som følge af at tråden har udført en wait() i Fork- objektets metoder)
Er vi færdige ?
Vink til opgave 4 synchronized void take_forks(Fork left,Fork right) { if (! left.available | ! right.available) { wait()};.. } // take_fork() skal kaldes af filosof. // hvor skal metoden placeres ? // og hvordan skal de blokerede filosoffer gen-aktiveres? // Opgave: Er det OK hvis take_forks() // er defineret i class Philosopher, // og kaldes inden 2*take_fork ?
RMI og tråde solver tråd Hvis metodekald i distribuerede objekter skal udføres samtidig, skal metoderne kaldes fra separate tråde i koordinatoren Koordinator
Javas tråd-implementation: Klasser, interfaces, modifier interface Runnable class Thread run() start()stop() sleep() setPriority(..) …. class Object wait()notify() …. Thread(Runnable t) // constructor Implementa- tionen af run() er trådens program En instans af class Thread gør programmet til separat tråd Metode-modifier: synchronized