Zadanie 2 (gniazda) =================== Zadanie to jest czescia "duzego" programu zaliczeniowego (patrz zadanie semestralne) i ma byc realizacja uproszonej wersji rozproszonego algorytmu wzajemnego wykluczania zaproponowanego przez Ricarta i Agrawale. Algorytm R-A: Kazdy proces, ktory chce wejsc do sekcji krytycznej, prosi o pozwolenie wszystkie pozostale procesy. Proces, ktory otrzymal od innego procesu prosbe o pozwolenie dziala nastepujaca: 1) jezeli sam wczesniej nie wyslal prosby (nie czeka na dostep), to odpowiada pozytywnie 2) jezeli sam wczesniej wyslal prosbe i jeszcze nie uzyskal wszystkich odpowiedzi, to o tym kto pierwszy wykona sekcje krytyczna decyduje czas wyslania prosb: a. jezeli zapytywany proces wyslal swoja prosbe pozniej, to takze odpowiada pozytywnie b. jezeli prosby zostaly wyslanie w tym samym momencie, to o kolejnosci decyduja priorytety (np. jezeli zapytany proces ma wyzszy numer to, odpowiada pozytywnie) c. w kazdym innym przypadku zapytywany proces wstrzymuje sie z odpowiedzia, az do chwili, gdy sam skonczy wykonywac swoja sekcje krytyczna - wowczas odpowiada pozytywnie wszystkim, ktorym jeszcze nie odpowiedzial. Schemat ogolny: W naszym zadaniu sekcja krytyczna bedzie utworzenie segmentu (rozproszonej) pamieci dzielonej o zadanym identyfikatorze. Klient, ktory chce utworzyc segment pamieci dzielonej, wysyla do serwera zlecenie dss_get(identyfikator). Serwer korzystajac z mechanizmu gniazd komunikuje sie ze wszystkimi innymi serwerami i przy pomocy algorytmu R-A ustala, czy dany klient moze utworzyc segment, czy nie. Odpowiedz (tak lub nie) jest wynikiem dzialania dss_get(). Uproszczenie algorytmu R-A polega na tym, ze serwer nie musi kolejkowac zapytan dotyczacych pobrania danego segmentu pamieci, gdyz zawsze tylko jeden klient moze utworzyc pamiec o danym identyfikatorze. Zadanie: Napisac program serwera oraz program klienta, ktory posluzy do przetestowania poprawnosci dzialania serwer(a/ow). * serwer (tak ma byc) * klient (tak moze byc) Zalozenia: 1. Klient moze wyslac tylko jedno zadanie dss_get() w danym momencie - operacja dss_get() jest blokujaca. 2. Serwer podczas startu otrzymuje plik z liste komputerow, na ktorych dzialaja (lub beda dzialac) inne serwery - nie ma zadnych dynamicznych zmian (dodawania, czy usuwania serwerow), lecz oczywiscie dzialajacy serwer moze ulec uszkodzeniu. 3. Serwery komunikuja sie za pomoca gniazd w dziedzinie Internetu. 4. Klienci komunikuja sie z serwerem za pomoca gniazd w dziedzinie Unix lub Internetu. 5. Wybor typu gniazd (SOCK_STREAM, czy SOCK_DGRAM) zalezy od implementatora. 6. Na jednym komputerze dziala tylko jeden serwer, ale moze byc wielu klientow, klient korzysta tylko z lokalnego serwera. 7. Numer portu, na ktorym dzialaja serwery jest powszechnie znany i unikatowy dla kazdego uzytkownika, piec ostatnich cyfr z numeru indeksu. 8. Format komunikatow przesylanych przy uzyciu gniazd zalezy od implementatora. 9. Serwer moze realizowac zadania (czyt. rzondania) od kilku klientow jednoczesnie (w obrebie danej maszyny). UWAGA! 1. W celu przetestowania zadania, kazdy musi przygotowac klientow tak, aby probowali dzialac, tzn. wysylac zadania dotyczace pobrania segmentow pamieci. Opracowanie testow jest czescia (istotna) zaliczenia. 2. Czas, ktorym stemplowane sa wiadomosci, to oczywiscie czas logiczny, wspolny dla serwerow biaracych udzial w "zabawie". Rozwiazanie zadania powinno zawierac zatem algorytm Lamporta korygowania zegarow logicznych - patrz: Gruzlewski, Weiss. "Programowanie wspolbiezne i rozproszone". ============================================= Pawel Janowski (email: janowski@mimuw.edu.pl) =============================================