StartAlgorytmyWzajemne wykluczanieAlgorytm Dijkstry
Baza Wiedzy
Wersja offline serwisu przeznaczona na urządzenia z systemem Android.

Darowizny
darowiznaWspomóż rozwój serwisu


Nagłówki RSS
Kanał artykuły
Kanał implementacje
Kanał komentarze
Kanał forum


Bookmarki









Sonda
Implementacji w jakim języku programowania poszukujesz?
 
Algorytm Dijkstry
Ocena użytkowników:+---- / 1
SłabyŚwietny 
Wpisany przez Tomasz Lubiński
wtorek, 26 lipca 2005 20:44
Algorytm ten jest uogólnieniem algorytmu Dekker'a na większą liczbę procesów i wykorzystuje się go do rozwiązania problemu wzajemnego wykluczania. Z zagadnieniem tym mamy do czynienia na przykład, gdy równolegle wykonywane procesy korzystają ze wspólnej pamięci. Przeprowadźmy symulację działania dwóch równolegle wykonywanych programów, z których jeden zwiększa wartość współdzielonej zmiennej w o 2, a drugi o 3 (wartość początkowa w to 0). Najpierw obydwa procesy pobierają wartość zmiennej w po czym pierwszy zwiększa jej wartość o 2 (0+2=2), a drugi o 3 (0+3=3). Po wykonaniu operacji procesy odsyłają wyniki. Jeżeli proces pierwszy zapisze swój wynik szybciej do zmiennej współdzielonej końcowym wynikiem będzie 3, jeżeli wolniej niż proces drugi w wyniku otrzymamy 2. W przypadku, gdy procesy wykonają obliczenia w sposób, który wykluczy jednoczesny dostęp do zmiennej współdzielonej wynik będzie prawidłowy.

Zapiszmy teraz problem wzajemnego wykluczania w sposób formalny:
Dany jest zbiór procesów sekwencyjnych komunikujących się przez wspólną pamięć. Każdy z procesów zawiera sekcję krytycznę, w której następuje dostęp do wspólnej pamięci. Procesy te są procesami cyklicznymi. Zakłada się ponadto:
  • zapis i oczyt wspólnych danych jest operacją niepodzielną, a próba jednoczesnych zapisów lub odczytów realizowana jest sekwencyjnie w nieznanej kolejności
  • sekcje krytyczne nie mają priorytetu,
  • względne prędkości wykonywania procesów są nieznane,
  • proces może zostać zawieszony poza sekcją krytyczna,
  • procesy realizujące instrukcje poza sekcją krytyczną nie mogą uniemożliwiać innym procesom wejścia do sekcji krytycznej,
  • procesy powinny uzyskac dostep do sekcji krytycznej w skończonym czasie.


Założenia dotyczące algorytmu są następujące:
Algorytm pozwala rozwiązać problem wzajemnego wykluczania dla n procesów.
Do komunikacji między równolegle wykonującymi się procesami służą 2 współdzielone zmienne:
  flag[1..n] - która dla każdego procesu przyjmuje trzy możliwe wartości: 0 - proces znajduje się poza sekcją krytyczną, 1 - proces ubiega się o wejscie do sekcji krytycznej, 2 - proces albo jest w drugim etapie ubiegania się o dostęp do sekcji krytycznej, albo wykonuje zadania w sekcji krytycznej,
  turn - określa, który z procesów ma pierszeństwo wejścia do sekcji krytycznej.
Algorytm Dijkstry ma następującą postać (zmienna i przyjmuje wartość będącą numerem procesu, czyli w procesie pierwszym 1, w procesie drugim 2, ...):
procedure process_i;
var //zmienne lokalne procesu
test, k, other, temp: integer;
begin
  while true do
   begin
   {część prgramu przed sekcją krytyczną}
  L: flag[i]:=1;
   other:=turn;
   while other<>i do
    begin
    test:=flag[other];
    if test=0 then turn:=i;
    other:=turn;
    end;
   flag[i]:=2;
   for k:=1 to n do
    if k<>i then
     begin
     test:=flag[k];
     if test=2 then goto L;
     end;
   {sekcja krytyczna}
   flag[i]:=0;
   {pozostała część programu}
   end;
end;


W algorytmie tym wejście do sekcji krytycznej odbywa się dwuetapowo. Najpierw proces, ustawia swoją flagę na wartość 1. Następnie sprawdza, który z procesów ma pierwszeństwo wejścia sekcji krytycznej. Jeżeli jest nim właśnie on, przechodzi do drugiego etapu (ustawia swoją flagę na wartość 2), w przeciwnym wypadku czeka, aż proces, który ma pierwszeństwo wyjdzie z sekcji krytycznej (pierwsza pętla while). Jeżeli proces, który miał pierwszeństwo nie znajduje się już w sekcji krytycznej, proces ubiegający się o wejście do niej ustawia pierwszeństwo na siebie (instrukcja if w pierwszej pętli while).
W drugim etapie proces sprawdza flagi wszystkich pozostałych procesów. Jeżeli wykryje, że któryś z procesów dostał się razem z nim do drugiego etapu następuje powrót do etapu pierwszego (instrukcja goto). Jeżeli natomiast proces ten jest jedynym procesem w drugim etapie, może on wejść do sekcji krytycznej.
Po wyjściu z sekcji krytycznej proces zdejmuje falgę (ustawia wartość zmiennej współdzielonej flag[i], na wartość 0), ustępując tym samym miejsce procesom czekającym w pierwszym etapie.
W skrajnym przypadku proces może nie uzyskać dostępu do sekcji krytycznej, gdyż inne (szybsze) procesy mogą go blokować w pierwszej z pętli while.



Autor Język programowania Komentarz Otwórz Pobierz Ocena
Tomasz Lubiński C/C++ Linux
Implementacja w C/C++
Implementacja w C/C++
++++- / 1
 
Dodaj własną implementację tego algorytmu
  • Zaloguj się na stronie
Plik:
Język programowania:
Komentarz:
  By móc dodać implementacje zaloguj się na stronie



Poprawiony: sobota, 11 czerwca 2011 19:05

Komentarze

 
photo
0 # Wojtek91 2011-11-11 11:30
A ile wynosi początkowa wartość turn dla każdego procesu?
Odpowiedz | Odpowiedz z cytatem | Cytować
 

Dodaj komentarz

Kod antysapmowy
Odśwież