programowanie
współbieżne
hahahaha rozwalilo mnie to
Podstawowe pojęcia współbieżności
Bezpieczeństwo
Żywotność
Blokada
Zagłodzenie
Uczciwość
Skutki stosowania współbieżności
Wstęp do procesów
Stany procesów
Deskryptor procesu
Zawartość deskryptora procesu
Fazy wykonania procesu
Atrybuty procesu
Dziedziczenie atrybutów
Procesy Posix
Tworzenie procesów
Funkcje
Makra
Akcje przy zakończeniu procesu
Pliki i funkcje dostępu do pliku
AÄ…cza nienazwane
Wykorzystanie
Funkcje
AÄ…cza nazwane
Wykorzystanie
Funkcja mkfifo
Funkcja select
Pamięć dzielona
Komunikacja przez wspólną pamięć w standardzie POSIX
Funkcje
Kolejki komunikatów
Kolejki komunikatów POSIX i zastosowania
Funkcje
Synchronizacja
Wzajemne wykluczanie
Operacje atomowe
Sekcja krytyczna
Warunki poprawnego rozwiÄ…zania sekcji krytycznej
Niesystemowe i systemowe metody ochrony sekcji krytycznej
Sprzętowa ochrona sekcji krytycznej
Semafory i ich zastosowanie
Ochrona sekcji krytycznej
Semafory nienazwane i nazwane POSIX
Funkcje
Monitory
Definicja
Zastosowanie
Oczekiwanie wewnÄ…trz monitora
Zmienne warunkowe
Funkcje
Implementacja semafora poprzez monitor
WÄ…tki
Wątki pojęcie i zasoby
Tworzenie
Synchronizacja
Funkcje
Mutexy
Zmienne warunkowe
Blokady czytelników i pisarzy
WirujÄ…ce blokady
Inwersja priorytetów
Ochrona przed inwersjÄ…
Metody dziedziczenia priorytetów
Metody pułapu priorytetów
Gniazdka
Interfejs gniazd
Funkcje
Serwer sekwencyjny
Serwer współbieżny
Sygnały
Sygnały i ich obsługa
Instalacja handlera sygnału
Blokowanie sygnałów
Sygnały a wątki
Timery
Posługiwanie się timerem
RPC
Zdalne wykonywanie procedur RPC
DO ZROBIENIA
Podstawowe pojęcia
WiÄ…zanie dynamiczne
Język opisu interfejsu IDL
Tworzenie aplikacji w standardzie Sun RPC
Linda
System Linda
Linda własności
Wspiera tworzenie aplikacji równoległych typu zarządca wykonawca
Kod niezależny od liczby procesów wykonawczych
Wspiera równoległość i komunikację międzyprocesową
Nakładanie się komunikacji i obliczeń
Nadaje się do systemów heterogenicznych (składających się z różnych maszyn)
Przestrzeń krotek
Operacje
Wyrażanie operacji synchronizacyjnych i komunikacyjnych
Problem producenta i konsumenta, czytelników i pisarzy
Rozwiązanie za pomocą semaforów
Rozwiązanie za pomocą monitorów
RozwiÄ…zanie za pomocÄ… zmiennych warunkowych
Rozwiązanie za pomocą mechanizmów języka Linda
Podstawowe pojęcia współbieżności
Procesy sekwencyjne - najpierw wykonuje siÄ™ jeden, potem drugi.
Procesy współbieżne - jeden z procesów rozpoczyna się przed zakończeniem
drugiego.
Procesy równoległe - j/w, ale wykonywane są na oddzielnych procesorach.
Bezpieczeństwo
Aplikacja jest bezpieczna, jeśli w przypadku działania współbieżengo nie wykrzaczy się.
Tzn:
Wszystkie sekcje krytyczne są prawidłowo zabezpieczone - jeśli nie, to wyniki mogą
być nieprawidłowe (jeden wątek nadpisujący dane innego (czyli wyścigi) itp),
Aplikacja na pewno siÄ™ nie zablokuje.
Można też powiedzieć, że aplikacja jest bezpieczna, jeśli nie zaprzestanie obsługi zleceń i
będzie je zawsze realizowała w prawidłowy sposób.
Żywotność
Gwarancja, że każda żądana akcja musi się kiedyś wykonać. Przykładowo, każdy klient
podłączany do serwera zostanie (prędzej czy pózniej) obsłużony.
Blokada
Zwana również zakleszczeniem. Generalnie chodzi o to, że każdy zablokowany proces
czeka na inny zablokowany proces, następuje błędne koło i żaden z nich się nie odblokuje.
Zagłodzenie
Zagłodzenie występuje gdy procesowi cały czas odmawia się dostępu do zasobów których
ten potrzebuje by wykonać zlecone mu zadanie.
Zagłodzenie procesu - na przykład, jeśli mamy dużo procesów o wysokim priorytecie i
planista systemowy nie jest na to przygotowany, to procesy o niskim priorytecie mogÄ…
nigdy nie dopchać się do zasobów, których potrzebują.
Uczciwość
Procesy żądające obsługi są traktowane zgodnie ze swoimi priorytetami lub jednakowo.
Rodzaje uczciwości:
Uczciwość słaba jeżeli proces nieprzerwanie zgłasza żądanie to kiedyś będzie ono
obsłużone.
Uczciwość mocna jeśli proces zgłasza żądanie nieskończenie wiele razy to w
końcu zostanie ono obsłużone.
Uczciwość liniowa jeśli proces zgłasza żądanie będzie ono obsłużone zanim
dowolny inny proces będzie obsłużony więcej niż raz.
Uczciwość typu FIFO żądania procesów są obsługiwane zgodnie z kolejnością ich
zgłaszania. (FIFO ang. First-In First-Out)
Skutki stosowania współbieżności
Korzyści wynikające z zastosowania współbieżności:
1. Polepszenie wykorzystania zasobów. Gdy jakiś proces czeka na niedostępny w
danej chwili zasób, procesor może wykonywać inny proces.
2. Podział zadania na procesy umożliwia wykonywanie ich na oddzielnych maszynach.
Prowadzi to do zrównoleglenia przetwarzania.
3. Podział dużego zadania na wiele mniejszych komunikujących się procesów
prowadzi do dekompozycji problemu. Przez co ułatwia ich implementację,
uruchamianie i testowanie przez wielu niezależnych programistów.
Trudności powstające przy implementacji aplikacji współbieżnych:
problem sekcji krytycznej
problem synchronizacji procesów
problem zakleszczenia
Procesy tworzące aplikację nie działają w izolacji. Muszą jakoś ze sobą współpracować co
prowadzi do:
- Konieczności wzajemnej wymiany informacji - komunikacja międzyprocesowa.
- Zapewnienia określonej kolejności wykonania pewnych akcji - problem synchronizacji.
Przedmiot programowania współbieżnego
Metodologia tworzenia aplikacji składających się z wielu komunikujących się i dzielących
zasoby procesów współbieżnych.
Wstęp do procesów
Stany procesów
Wyróżniamy 3 stany procesów:
Wykonywany - proces, który aktualnie się wykonuje. Tutaj nie ma wiele do
dyskusji.
Gotowy - proces, który aktualnie się nie wykonuje. Mógłby, ale brakuje dla niego
zasobów (np. mamy tylko jeden procesor, więc nie może wykonywać się więcej niż
jeden proces jednocześnie).
Zablokowany - Proces, który na coś czeka, np. na zakończenie wątku
(pthread_join()), podprocesu (wait()), dostępu do sprzętu itp.
Zombie - Proces, który się zakończył, ale jego proces macierzysty nie wykonał
funkcji wait()
Jak widać na powyższym rysunku, proces wykonywany może zmienić stan na gotowy i
odwrotnie (głównie ze względu na planistę systemowego, przydział czasu procesora itp).
Ale już zablokować może się tylko gdy jest wykonywany (no bo w sumie ciężko, żeby
wywołał wait() w trakcie gotowości), a z zablokowanego może stać się tylko gotowy.
Proces może zakończyć się w każdej chwili, a po uruchomieniu przechodzi od razu do
stanu gotowości.
Deskryptor procesu
(ang. process descriptor) rekord w którym system operacyjny utrzymuje wszystkie
informacje niezbędne do zarządzania procesem.
Zawartość deskryptora procesu
PID
Stan procesu
Wskaznik na poprzedni i następny deskryptor
Wskaznik do poprzedniego i następnego procesu w kolejce (zablokowanych,
gotowych itp)
Informacje o szeregowaniu (priorytet itp)
Informacje o obsłudze sygnałów (sygnały dostarczane, zablokowane)
Informacje o hierarchii procesów (proces macierzysty, procesy potomne)
Kontekst procesu (rejestry)
Informacje o zużytym czasie procesora
Nazwa pliku, z którego proces został stworzony
UID, GID, EUID, EGID
Rozmiar segmentu kodu, danych i stosu
Położenie segmentu kodu, danych i stosu
Informacje o stronach zajmowanych przez proces
Katalog bieżący i macierzysty
Informacja o terminalu sterujÄ…cym
UMASK - wzorzec uprawnień dla nowych plików
Wskaznik na tablicę deskryptorów plików otwartych
Fazy wykonania procesu
1. Tworzenie :
Alokacja deskryptora procesu, przydział PID
Ustalenie zmiennych otoczenia zwykle dziedziczone z procesu macierzystego
2. Aadowanie
Załadowanie segmentu kodu i danych oraz inicjacji stosu. Aadowanie wykonywane
jest przez oddzielny watek ładujący aby nie blokować administratora procesu Proc.
3. Faza wykonania
Po zaladowaniu nowy proces jest umieszczany w kolejce procesów gotowych, uruchamian
4. Faza zakonczenia
Zakończenie procesu może być zainicjowane przez sam proces gdy wykona on
funkcje exit, lub poprzez wysłany z zewnątrz sygnał. Zakonczenie sklada sie z
dwu etapów.
a. Zwolnienie zasobów - proces zwalnia wszystkie zajmowane zasoby jak
pamiec, nazwy, itd. oraz likwiduje interakcje z innymi procesami. Po
wykonaniu tej fazy zajmuje tylko deskryptor.
b. Zawiadomienie procesu macierzystego o zakończeniu. Dopóki proces
macierzysty nie wykona funkcji wait lub waitpid konczony proces pozostaje
w stanie zombie . Aby uniknac pozostawania procesów w stanie zombie
mozna ustawic reakcje na sygnal SIGCHLD w funkcji signal na SIG_IGN.
Atrybuty procesu
PID - identyfikator procesu
PPID - PID procesu macierzystego
UID - identyfikator użytkownika
GID - identyfikator grupy użytkownika
SID - identyfikator sesji
PGRP - identyfikator grupy procesów
priorytet procesu
CWD - katalog bieżący
katalog główny
otoczenie procesu
Dziedziczenie atrybutów
Proces potomny dziedziczy większość atrybutów procesu macierzystego, ale ma swoje PID,
PPID oraz własne kopie deskryptorów otwartych plików.[zródło]
Procesy Posix
Tworzenie procesów
fork() tworzy kopię bieżącego procesu. Od procesu macierzystego różni się PIDem,
Parent PIDem, a dla wszystkich otwartych plików w procesie macierzystym proces
potomny otrzymuje kopie ich deskryptorów (zamiast korzystać z deskryptorów
utworzonych przez proces macierzysty).
Funkcja fork() tworzy deskryptor nowego procesu oraz kopiÄ™ segmentu danych i stosu.
Funkcje
fork() - Utworzenie kopii procesu bieżącego
exec() - Zastąpienie procesu bieżącego innym procesem rodzina funkcji.
wait(), waitpid() - Czekanie na zakończenie procesu
exit() - Zakończenie procesu
spawn() - Utworzenie procesu potomnego rodzina funkcji.
Makra
WEXITSTATUS - Zwraca kod powrotu y przekazany przez funkcjÄ™ exit(y) z procesu
potomnego
WTERMSIG - jeśli proces był zakończony przez sygnał, to zwraca numer sygnału
WIFEXITED - jeśli proces potomny był zakończony normalnie, to zwraca > 0
WIFSIGNALED - zwraca >0, jeśli proces potomny został zakończony przez nie
obsłużony sygnał
Akcje przy zakończeniu procesu
Należy zakończyć komunikację z innymi procesami
Należy zwolnić zajmowane zasoby
Należy zaczekać na zakończenie procesów potomnych (bo inaczej są one
adoptowane przez init)
1. Zamykane sÄ… otwarte pliki i strumienie
2. Najmłotszy bajt z kodu powrotu x jest przekazywany do zmiennej odczytywanej
przez funkcję wait() w procesie macierzystym. Kod powrotu jest zapamiętywany
w deskryptorze.
3. Jeśli proces macierzysty wywołał wait() albo waitpid(), to zostaje on
odblokowany a deskryptor jest usuwany
4. Jeśli jednak nie wywołał tych funkcji, to proces potomny przechodzi do stanu
zombie, a kod powrotu czeka sobie w deskryptorze.
5. Proces macierzysty otrzymuje sygnał SIGCHLD.
Pliki i funkcje dostępu do pliku
open() - funkcja otwierająca plik (lub np. urządzenie będące plikiem). Potrafi
utworzyć plik, jeśli takowy nie istnieje, ale to zależy od ustawień oflag. Funkcja
zwraca deskryptor pliku (uchwyt), którego używamy do identyfikacji pliku.
creat() - funkcja tworzÄ…ca nowy plik. W argumencie podajemy nazwÄ™ pliku i
atrybuty (prawa dostępu). Funkcja, podobnie jak open(), zwraca deskryptor pliku.
read() - Za parametr bierze deskryptor pliku, bufor docelowy i ilość bajtów do
odczytu, a co robi z tą wiedzą to już można się domyśleć. Czyta w bieżącej pozycji
w pliku, jeśli nam to nie pasuje to pozostaje lseek().
write() - Parametry to deskryptor pliku, bufor zawierający dane do zapisu i ilość
bajtów do zapisania. Analogicznie jak read(), ale na odwrót.
close() zamyka plik.
lseek() - Pozwala zmieniać obecną pozycję w pliku. Argumenty to deskryptor
pliku, offset stanowiący o ile mamy się przesunąć i flagę która decyduje, czy
przesuwamy się względem bieżącej pozycji, początku lub końca pliku.
{,f,l}stat() - Zwraca informacje o pliku (inode, uprawnienia itp).
fcntl() - Zmienia atrybuty pliku.
unlink(), remove() - usuwa plik
dup(), dup2() - duplikuje deskryptor pliku. Można robić takie rzeczy jak np.
czitować program żeby myślał, że pisze na stdout a w rzeczywistości pisałby do
pliku.
AÄ…cza nienazwane
Wykorzystanie
Prosta komunikacja pomiędzy procesem macierzystym i potomnym, nie ma możliwości
wymiany deskryptora pliku, w którym znajduje się łącze nienazwane inaczej niż gdy oba
procesy są w relacji macierzysty/potomny. Ten kanał komunikacji jest jednostronny dla
danego procesu, tzn np. macierzysty tylko czyta, a potomny tylko pisze.
1. Tworzymy łącze za pomocą funkcji pipe(), której parametrem jest wskaznik na
dwuelementowÄ… tablicÄ™ int - w niej znajdÄ… siÄ™ deskryptory.
2. fork()ujemy sobie program
3. W procesie potomnym zamykamy nieużywany deskryptor za pomocą close(), np
jeśli tylko będziemy pisać, to zamykamy deskryptor do pisania (close(fd[1])),
po czym czytamy/zapisujemy jak z normalnym plikiem
4. W procesie macierzystym analogicznie
5. Na końcu robimy close() na pozostałych deskryptorach, z których korzystaliśmy i
to tyle
Funkcje
pipe() - tworzy Å‚Ä…cze nienazwane.
open(), read(), write(), close() - jak w przypadku plików. Uwaga: nie
używamy open() w przypadku łącz nienazwanych, bo nie mamy pliku, który
chcemy otworzyć - zamiast tego korzystamy z pipe().
flock() - blokuje plik, pozwalając na synchronizację dostępu do niego pomiędzy
kilkoma procesami.
fileno() - zwraca deskryptor pliku dla argumentu FILE*.
AÄ…cza nazwane
Wykorzystanie
Aącza nazwane mogą być używane przez niepowiązane ze sobą procesy. Są to po
prostu specjalne pliki, które są normalnie dostępne w systemie plików. Pliki te giną po
wyłączeniu komputera.
1. Tworzymy plik FIFO za pomocÄ… mkfifo(),
2. Otwieramy plik poprzez open(),
3. read() i write() jak kto potrzebuje,
4. tradycyjne close().
Funkcja mkfifo
Strona w manie - tworzy Å‚Ä…cze nazwane, jako argument przyjmuje nazwÄ™ pliku FIFO oraz
prawa dostępu do pliku.
int mkfifo(char * path, mode_t mode)
path - Nazwa pliku FIFO (ze ścieżką)
mode - Prawa dostępu do pliku .
Funkcja zwraca: 0 sukces, -1 błąd.
Funkcja select
Funkcja ta blokuje bieżący proces do momentu, kiedy dany deskryptor stanie się gotowy
albo wystąpi błąd. Można mu ustawić timeout, czyli czas, po którym funkcja daje sobie
spokój, dłużej nie czeka tylko zwraca błąd.
Tutaj nie ma wiele do mówienia, lepiej przeczytać stronę manuala.
Pamięć dzielona
Komunikacja przez wspólną pamięć w standardzie
POSIX
1. Alokujemy pamięć dzieloną poprzez funkcję shm_open(), w atrybutach której
znajduje się nazwa segmentu pamięci dzielonej i jej atrybuty, i która zwraca
deskryptor pliku,
2. Poprzez ltrunc() lub ftruncate() ustalamy obszar zajmowanej pamięci,
3. Używając mmap() inicjujemy zmienną w pamięci dzielonej, zwykle ładując tam
wcześniej zdefiniowaną strukturę; jako wynik owej funkcji otrzymujemy wskaznik
do zmiennej
4. Korzystamy sobie ze struktury normalnie
5. Zwalniamy nazwę pamięci dzielonej za pomocą shm_unlink(nazwa).
Przykład: https://bitbucket.org/fleg/glupotki/src/831bc7d2d314/wspolbiezne/lab5/semafory/
main.c
Funkcje
shm_open()
shm_unlink()
ftruncate()
mmap()
Kolejki komunikatów
Kolejki komunikatów POSIX i zastosowania
SÄ… widziane jako plik specjalny
Komunikaty w kolejce zachowują swoją strukturę; są separowane. Nie jest już
tak, jak w FIFO, gdzie po prostu czytamy tyle a tyle bajtów. Komunikaty w kolejce
mogą być różnej długości.
Komunikaty w kolejce mogą mieć różne priorytety.
Kolejki komunikatów są wygodne, gdy:
Proces wysyłający komunikaty nie może zostać wstrzymany,
Proces wysyłający nie wymaga informacji zwrotnej od adresata,
Konieczne jest przekazywanie danych od producenta do konsumenta.
Korzystanie z kolejki w praktyce: (kod zródłowy)
1. Za pomocÄ… struktury mq_attr ustawiamy opcje kolejki
2. Tworzymy/otwieramy kolejkę komunikatów za pomocą funkcji mq_open(), która
za parametry przyjmuje nazwÄ™ kolejki, tryb otwarcia (zapis/odczyt), uprawnienia i
wskaznik na strukturÄ™ z punktu 1, a zwraca mqd_t,
3. operujemy sobie na kolejce za pomocÄ… mq_send() lub mq_receive(),
4. zamykamy kolejkÄ™ za pomocÄ… mq_close(),
5. kasujemy kolejkÄ™ za pomocÄ… mq_unlink(). Kasowanie to nie powinno
spowodować problemów, jeśli jakiś inny proces aktualnie korzysta z kolejek
(w końcu nie interesuje go ścieżka do pliku itp, a licznik otwarcia nadal będzie
większy od 0), ale to tylko moje przemyślenie.
Funkcje
mq_open
mq_receive
mq_send
mq_attr
mq_notify
Synchronizacja
Wzajemne wykluczanie
Wzajemne wykluczanie - wymaganie aby ciÄ…g operacji na pewnym zasobie (zwykle
pamięci) był wykonany w trybie wyłącznym przez tylko jeden z potencjalnie wielu
procesów.
Operacje atomowe
Operacje, które nie mogą zostać przerwane, np. przez przełączenie procesu.
Sekcja krytyczna
Sekcja, która może być wykonywana równolegle/współbieżnie przez tylko jeden proces.
Warunki poprawnego rozwiÄ…zania sekcji krytycznej
Rozwiązanie problemu wzajemnego wykluczania musi spełniać następujące warunki:
1. W sekcji krytycznej może być tylko jeden proces to znaczy instrukcje z sekcji
krytycznej nie mogą być przeplatane.
2. Nie można czynić żadnych założeń co do względnych szybkości wykonywania
procesów.
3. Proces może się zatrzymać w sekcji lokalnej nie może natomiast w sekcji
krytycznej. Zatrzymanie procesu w sekcji lokalnej nie może blokować innym
procesom wejścia do sekcji krytycznej.
4. Każdy z procesów musi w końcu wejść do sekcji krytycznej.
A nie chodzi o to?
Niesystemowe i systemowe metody ochrony sekcji
krytycznej
DO UZUPEANIENIA
Systemowe:
1. Blokowanie przerwań
2. Metoda zmiennej blokującej (nieprawidłowa)
Niesystemowe:
1. Wirujące blokady (ang. Spin Locks) wykorzystujące sprzętowe wsparcie w postaci
instrukcji sprawdz i przypisz oraz zamień. Stosuje się je do synchronizacji wątków
ze względu na mały narzut operacji systemowych.
2. Blokowanie przerwań do ochrony wewnętrznych sekcji krytycznych systemu
operacyjnego.
Sprzętowa ochrona sekcji krytycznej
DO UZUPEANIENIA
TAS - sprawdz i przypisz
CAS - porównaj i zamień
XCHG - zamień
Semafory i ich zastosowanie
Semafor - jest obiektem abstrakcyjnym służącym do kontrolowania dostępu do
ograniczonego zasobu. Semafory są szczególnie przydatne w środowisku gdzie wiele
procesów lub wątków komunikuje się przez wspólną pamięć.
Ochrona sekcji krytycznej
1. Tworzymy semafor za pomocą funkcji sem_init(), której pierwszym parametrem
jest wskaznik na semafor (zmienna typu semaphore), a drugim poczÄ…tkowa
wartość semafora.
2. Wywołujemy sem_wait(). Funkcja ta dekrementuje wartość semafora jeśli
jest on dodatni, a jeśli jest równy 0 to blokuje proces bieżący, który zostanie
odblokowany wtedy, gdy inny proces wywoła na tym samym semaforze
sem_post().
3. Wykonujemy kod sekcji krytycznej
4. Wywołujemy sem_post(), który albo odblokowuje inny proces oczekujący na tym
semaforze, albo inkrementuje wartość semafora.
Generalnie kwestia tej zmiennej, zera itp jest dość prosta, ale trzeba sobie to wyobrazić.
Semafory nienazwane i nazwane POSIX
Wyróżnione są tu dwa typy semaforów:
1. Semafory nienazwane - dostęp do semafora nienazwanego następuje po adresie
semafora. StÄ…d nazwa semafor nienazwany.
2. Semafory nazwane - identyfikowane sÄ… w procesach poprzez ich nazwÄ™. Na
semaforze nazwanym operuje siÄ™ tak samo jak na semaforze nienazwanym z
wyjątkiem funkcji otwarcia i zamknięcia semafora.
Semafory nienazwane nadają się do synchronizacji wątków w obrębie jednego procesu.
Dostęp do semafora nienazwanego następuje poprzez jego adres. Może on być także
użyty do synchronizacji procesów o ile jest umieszczony w pamięci dzielonej. Dostęp do
semaforów nazwanych następuje poprzez nazwę. Ten typ semaforów bardziej nadaje się
synchronizacji procesów niż wątków. Semafory nienazwane działają szybciej niż nazwane.
Funkcje
sem_open
sem_init
sem_wait
sem_post
Monitory
Definicja
Monitor jest strukturalnym narzędziem synchronizacji.
Zmienne i procedury, które na nich operują są zebrane w jednym module. Dostęp
do zmiennych monitora jest możliwy tylko i wyłącznie za pomocą procedur
monitora.
Tylko jeden proces może w danej chwili wywoływać procedury monitora. Każdy
inny proces chcący wywołać procedurę monitora zostanie zablokowany, aż pierwszy
proces nie skończy.
Można wstrzymywać i wznawiać procedury monitora za pomocą zmiennych
warunkowych, na których można wykonywać operacje wait() i signal().
Zastosowanie
DO ZROBIENIA
Oczekiwanie wewnÄ…trz monitora
Podejrzewam, że chodzi o wait().
Mianowicie, w trakcie wykonywania procedury monitora można wywołać wait(), po czym
obecny proces zostanie wstrzymany i wrzucony na koniec kolejki procesów oczekujących
na mieszanie w monitorze lub jakiejś kolejki uprzywilejowanej (zależy od implementacji),
a dostęp do monitora zostaje przekazany innemu procesowi.
Ma to sens w przypadku, kiedy wykonujemy jakÄ…Å› operacjÄ™ na monitorze, ale okazuje siÄ™,
że musimy czekać na jeszcze coś innego. Wtedy, zamiast blokować inne procesy czekające
na dostęp do monitora i bezczynnie czekać, możemy wpuścić kogoś samemu czekając.
Zmienne warunkowe
DO ZROBIENIA
Funkcje
wait
signal
noempty
notify
broadcast
Implementacja semafora poprzez monitor
DO ZROBIENIA
WÄ…tki
Wątek elementarna jednostka szeregowania korzystająca z zasobów procesu.
Wątki wykonywane w ramach jednego procesu dzielą jego przestrzeń adresową i
inne zasoby procesu.
W ramach jednego procesu może się wykonywać wiele wątków
Własności wątków
Koszt utworzenia i przełączania wątku jest mniejszy niż procesu.
Dane statyczne procesu są dla wątków działających w ramach jednego
procesu wzajemnie widoczne.
Wykonanie każdego wątku przebiega sekwencyjnie, każdy wątek ma swój
licznik rozkazów.
Wątki mogą być wykonywane na oddzielnych procesorach co umożliwia
przyspieszenie obliczeń.
Ponieważ wątki dzielą wspólne dane konieczna jest synchronizacja dostępu
do tych wspólnych danych.
Wątki pojęcie i zasoby
Wątek dzieli ze swym procesem macierzystym następujące zasoby:
Dane statyczne (segment danych)
Deskryptory otwartych plików, blokady plików
Maskę tworzenia plików (umask)
Åšrodowisko
Katalog macierzysty i główny
Limity zasobów (setrlimit)
Timery
Sesję, użytkownika, grupę, terminal sterujący
Zasoby własne wątku:
Identyfikator wÄ…tka (thread ID)
Maska sygnałów
Zmienna errno
Priorytet i strategiÄ™ szeregowania
Atrybuty i zasoby własne wątku:
Identyfikator wątku TID (ang.Thread Identifier) - każdy watek ma unikalny w
1.
ramach procesu identyfikator. Jest to liczba całkowita. Pierwszy wątek ma TID
1, następny 2 itd.
Zestaw rejestrów (ang. Register set) - każdy wątek posiada własny obszar
2.
pamięci w którym pamiętany jest zestaw rejestrów procesora (tak zwany
kontekst procesora). Gdy watek jest wywłaszczany lub blokowany w obszarze
tym pamiętane są rejestry procesora. Gdy watek będzie wznowiony obszar
ten jest kopiowany do rejestrów procesora.
Stos (ang. Stack) - każdy wątek ma swój własny stos umieszczony w
3.
przestrzeni adresowej zawierającego go procesu. Na stosie tym pamiętane są
zmienne lokalne wÄ…tku.
Maska sygnałów (ang. Signal mask) - każdy wątek ma swą własną maskę
4.
sygnałów. Maska sygnałów specyfikuje które sygnały mają być obsługiwane
a które blokowane. Początkowa maska jest dziedziczona z procesu
macierzystego.
Obszar TLS wątku (ang. Thread Local Storage) każdy wątek ma
5.
pewien obszar pamięci przeznaczony na utrzymywanie różnych danych
administracyjnych takich jak TID, PID, poczÄ…tek stosu, kod ewentualnego
błędu errno i inne dane. Obszar TLS jest odpowiednikiem deskryptora
procesu.
Procedura zakończenia (ang. Cancellation Handler) - gdy wątek się kończy
6.
wykonywana jest procedura zakończenia w ramach której zwalniane są
zasoby wÄ…tku.
Tworzenie
Tworzenie wÄ…tku
Nowy wÄ…tek tworzy siÄ™ przy pomocy funkcji pthread_create. Funkcja ta tworzy
wątek, którego kod znajduje się w funkcji podanej jako argument func. Wątek jest
uruchamiany z parametrem arg, a informacja o nim jest umieszczana w strukturze
thread.
Synchronizacja
W bibliotece pthreads do zapewnienia wyłączności dostępu do danych stosuje się
mechanizm muteksu (ang. mutex). Nazwa ta pochodzi od słów Mutual exclusion
czyli
wzajemne wykluczanie.
Funkcje
pthread_create
pthread_join - Funkcja pthread_join zawiesza działanie wołającego wątku
aż do momentu, gdy watek podany jako argument nie zakończy działania.
-odczytuje wartość zakończenia wątku
pthread_exit
Mutexy
mutex_init
mutex_lock - Zajęcie muteksu - zapewnia wyłączność w korzystaniu z zasobu.
mutex_unlock - Zwolnienie muteksu - zwalnia użyty i zablokowany wcześniej
zasób. Działanie funkcji mutex_unlock zależy od tego czy inne wątki czekają
zblokowane na muteksie:
Brak wątków zablokowanych na muteksie stan muteksu zostaje
1.
zmieniony na wolny.
Są wątki zablokowane na muteksie jeden z czekających wątków zostaje
2.
odblokowany
Zmienne warunkowe
Zmienna warunkowa jest narzędziem do blokowania wątku wewnątrz sekcji
krytycznej aż do momentu gdy pewien warunek zostanie spełniony. Warunek ten
może być dowolny i niezależny od zmiennej warunkowej. Zmienna warunkowa
musi być użyta w połączeniu z muteksem o ile konstrukcja ma zapewnić własności
monitora.
cond_init
cond_wait - Zawieszenie wÄ…tku w kolejce.
cond_signal - Wznowienie wÄ…tku zawieszonego w kolejce danej zmiennej
warunkowej.
cond_broadcast - Wznowienie wszystkich wątków zawieszonych w kolejce
danej zmiennej warunkowej.
Blokady czytelników i pisarzy
Zasada działania blokad czytelników i pisarzy:
Odczyt może być wykonywany współbieżnie do innych odczytów
Zapis musi być wykonywany w trybie wyłącznym względem innych zapisów
lub odczytów.
Stan blokady:
Wolna
Zajęta do odczytu być może przez wiele wątków czytających
Zajęta do zapisu
WirujÄ…ce blokady
Wirujące blokady są środkiem zabezpieczania sekcji krytycznej. Wykorzystują
jednak czekanie aktywne zamiast przełączenia kontekstu wątku tak jak się to dzieje
w muteksach.
Blokada może być w dwóch stanach:·
Wolna
Zajęta
pthread_spin_init - podczas inicjacji wirujÄ…cej blokady definiujemy czy mogÄ…
operować wątki należące do różnych procesów czy tylko wątki należące do
tego samego procesu
pthread_spin_lock - Zajęcie blokady - Działanie funkcji zależy od stanu
blokady. Gdy blokada jest wolna następuje jej zajęcie. Gdy blokada jest
zajęta wątek wykonujący funkcję pthread_spin_lock(...)ulega
zablokowaniu do czasu gdy inny wÄ…tek nie zwolni blokady wykonujÄ…c funkcjÄ™
pthread_spin_unlock
pthread_spin_unlock - zwolnienie blokady - Działanie funkcji zależy od stanu
blokady. Gdy są wątki czekające na zajęcie blokady to jeden z nich zajmie
blokadę. Gdy żaden wątek nie czeka na zajęcie blokady będzie ona
zwolniona.
Inwersja priorytetów
Dzika sytuacja, gdy dwa lub więcej wątki o różnych priorytetach używają wspólnego
zasobu chronionego przez pewien mechanizm zapewnienia wzajemnego
wykluczania (np. muteks)
Inwersja priorytetów zjawisko polegające na wykonywaniu się wątku o niższym
priorytecie mimo, iż wątek o wyższym priorytecie pozostaje gotowy. Inwersja
priorytetów może się pojawić gdy wątki o różnych priorytetach używają wspólnego
muteksu lub podobnego mechanizmu synchronizacyjnego.
Ochrona przed inwersjÄ…
W systemach czasu rzeczywistego stosowane są dwie strategie postępowania z
problemem inwersji priorytetów. Jest to:
1. Dziedziczenie priorytetu (ang.Priority Inheritance)
2. Zastosowanie stosowanie protokołu wykorzystującego tzw. pułap priorytetów
(ang.
Priorty Ceiling)
Metody dziedziczenia priorytetów
Dziedziczeniem priorytetu polega na tym, że gdy wątek W3 o wyższym priorytecie
próbuje zająć muteks zajęty już przez wątek W1 o priorytecie niższym, to system
podwyższa chwilowo priorytet wątku W1 zajmującego muteks do wysokości
priorytetu wątku W3. Dzięki podwyższonemu priorytetowi wątek W1 szybciej wykona
swe zadanie i zwolni muteks. Po zwolnieniu muteksu wÄ…tkowi W1 zostaje mu
przywrócony pierwotny priorytet.
I piękna definicja
Dziedziczeniem priorytetu tymczasowe zwiększenie priorytetu wątku
posiadającego zasób do najwyższego priorytetu z priorytetów wątków ubiegających
się o zajęcie tego zasobu. Po zwolnieniu zasobu wątkowi przywracany jest
poczÄ…tkowy priorytet.
Dodatkowa wiedza
Protokół dziedziczenia priorytetów działa prawidłowo w przypadku użycia jednego
typu zasobu. Gdy używana jest większa liczba zasobów może dojść do różnych
niekorzystnych zjawisk jak:
blokowanie przechodnie
zakleszczenie.
Metody pułapu priorytetów
Każdemu chronionemu zasobowi (w tym przypadku jest to muteks) przypisuje
się pewien określony statyczny priorytet. Priorytet ten powinien być wyższy od
najwyższego priorytetu z tych wątków które o dany zasób będą konkurowały. Gdy
jakiś wątek będzie próbował zająć zasób to zostanie mu tymczasowo przydzielony
priorytet zwiÄ…zany z tym
zasobem. Po zwolnieniu zasobu priorytet wątku wróci do wielkości wyjściowej.
Protokół z pułapem priorytetu (ang. priority ceiling protocol)
W protokole z pułapem priorytetu następuje tymczasowe zwiększenie priorytetu w
wątku usiłującego zająć zasób do pewnego ustalonego priorytetu (wyższego
od priorytetu jakiegokolwiek wątku konkurującego o zasób). Wszystkim wątkom
konkurujące o zasób zostaje tymczasowo nadany ten jednakowy priorytet. Dzięki
temu że watek zajmujący zasób zyskuje chwilowo priorytet wyższy niż jakiekolwiek
inny wątek konkurujący o zasób ma on szansę zakończyć operację na zasobie bez
wywłaszczenia.
Zalety protokołu:
Protokół zapobiega powstawaniu zakleszczeń.
Zapewnia dobry czas oczekiwania na zasób (dla najgorszego przypadku)
poprzez wątek o najwyższym priorytecie. Czas ten równy jest długości
najdłuższej sekcji krytycznej wątków o niższym priorytecie.
Wady protokołu:
Należy z góry wyznaczyć zbiór wszystkich wątków które będą konkurowa ły o
zasób i jako pułap priorytetu przyjąć najwyższy priorytet z zadań z tego zbioru
+ 1 . Może to być czasochłonne lub nawet niemożliwe.
Posiada zły średni czas odpowiedzi z związku z narzutami na implementację.
Gniazdka
Interfejs gniazd
Jednolity interfejs API (Application Program Interface) do mechanizmów
komunikacji sieciowej.
Główna idea gniazdek polega na użyciu do komunikacji (lokalnej i zdalnej)
tego samego mechanizmu, co dostępu do plików. Jest to mechanizm oparty o
deskryptory plików i funkcje read, write .
Termin gniazdko ma dwa znaczenia:
Biblioteka + funkcje interfejsowe (API).
1.
Końcowy punkt komunikacji
2.
Biblioteka gniazdek maskuje mechanizmy transportu sieci.
Własności gniazd:
Gniazdo jest identyfikowane przez liczbę całkowitą nazywaną deskryptorem
gniazda
Gniazdo można nazwać i wykorzystywać do komunikacji z innymi gniazdami
w tej samej domenie komunikacyjnej
Komunikacja bezpołączeniowa - Komunikacja bez
kontroli połączenia
Klient:
Tworzy gniazdko - socket
Nadaje gniazdku adres - bind (konieczne przy odbiorze)
Nadaje lub odbiera dane - sendto, recfrom, write, read, recv, send
Serwer:
Tworzy gniazdko - socket
Nadaje gniazdku adres - bind (konieczne przy odbiorze)
Nadaje lub odbiera dane - sendto, recfrom, write, read, recv, send
Funkcja recfrom - Odbiór danych z gniazdka - umożliwia odczyt bajtów z
gniazdka znajdującego sięw stanie niepołączonym jak i połączonym.
Funkcja sendto - Zapis do gniazdka - Funkcja sendto umożliwia wysłanie
bajtów do gniazdka znajdującego się w stanie nie połączonym jak i połączonym.
Komunikacja połaczeniowa - Transmisja z kontrolą
połączenia
Klient:
1. Tworzy gniazdko socket
2. Nadaje gniazdku adres bind (konieczne przy odbiorze)
3.AÄ…czy siÄ™ z serwerem connect
4. Nadaje lub odbiera dane write, read, recv, send
Serwer:
1. Tworzy gniazdko socket
2. Nadaje gniazdku adres bind (konieczne przy odbiorze)
3. Wchodzi w tryb akceptacji po łączeń listen
4. Oczekuje na po Å‚Ä…czenia accept
Gdy połączenie zostanie nawiązane:
Tworzy dla tego po Å‚Ä…czenia nowe gniazdko
1.
Nadaje lub odbiera dane - write, read, recv, send
2.
Zamyka gniazdko
3.
Funkcje
connect - Połączenie ze zdalnym gniazdkiem. Funkcja powoduje próbę nawiązania
połączenie ze zdalnym gniazdkiem wyspecyfikowanym jako adres.
listen - Wprowadzenie serwera w stan gotowości do nawiązania połączenia
accept - Nawiązanie połączenia przez serwer -
Działanie funkcji accept:
Wywołanie accept może być blokujące. Gdy przychodzi nowe połączenie
następuje odblokowanie procesu bieżącego i wykonanie następujących czynności:
Pobranie pierwszego połączenie z kolejki oczekujących połączeń.
1.
Utworzenie nowego gniazdka o identycznych własnościach jak gniazdko
2.
utworzone poleceniem socket.
Alokacja nowego deskryptora pliku dla gniazdka.
3.
Nadanie wartości parametrom name i namelen.
4.
read - Odczyt z gniazdka Funkcja jest używana do odbioru danych z gniazdka
w trybie połączeniowym. Funkcja powoduje odczyt z gniazdka i umieszczenie
odczytanych n bajtów w buforze.
write - j.w tylko w 2 strone
recv - Funkcja jest używana do odbioru danych z gniazdka w trybie
połączeniowym lub bezpołączeniowym. - podobnie jak read, ale występuje
tu dodatkowy 3 parametr z flagami: MSG_WAITALL - Funkcja czeka na
tyle bajtów ile wymieniono w wywołaniu, MSG_OOB - Odbiór danych poza
pasmem znaczenie zależy od protokołu, MSG_PEEK Dane odczytane na
próbę, nie znikają z bufora
send - analogicznie
Serwer sekwencyjny
Serwer sekwencyjny to serwer składający się z jednego tylko procesu. W danej chwili
może on obsługiwać tylko jednego klienta.
Klient:
1. Lokalizacja serwera
2. Utworzenie komunikatu specyfikującego żądanie
3. Wysłanie komunikatu do procesu serwera
4. Odbiór odpowiedzi.
5. Wykorzystanie wyniku.
Serwer:
1. Rejestracja nazwy własnej w serwerze nazw.
2. Odbiór zlecenia.
3. Identyfikacja zlecenia
4. Realizacja zlecenia.
5. Wysłanie odpowiedzi do klienta
Serwer współbieżny
Współbieżne działanie serwera pozwala, w sytuacji gdy do serwera łączy się wielu
klientów, na ich współbieżne obsłużenie.
Schemat działania serwera współbieżnego
1.
Tworzy gniazdko - socket
2.
Nadaje gniazdku adres - bind (konieczne przy odbiorze)
3.
Wchodzi w tryb akceptacji połączeń - listen
4.
Oczekuje na połączenia - accept
5.
Gdy przychodzi nowe połączenie funkcja accept zwraca identyfikator
nowego gniazdka. To gniazdko będzie używane w połączeniu z klientem. Dla
połączenia tworzy się nowy proces i przechodzi się do 4.
Proces obsługujący połączenie:
Korzysta z nowego gniazdka którego numer jest przekazany jako parametr
Nadaje lub odbiera dane - write, read, recv, send
1.
Zamyka gniazdko
2.
Sygnały
Sygnały i ich obsługa
Sygnał mechanizm asynchronicznego powiadamiania procesów o zdarzeniach
zwykle awaryjnych.
Sygnały mogą być generowane przez:
System operacyjny, zwykle po wykonaniu nieprawidłowej operacji.
1.
Z konsoli operatorskiej poprzez polecenia kill i slay.
2.
Z programu aplikacyjnego poprzez funkcje (np. kill, raise, abort, alarm, i inne)
3.
oraz timery.
Proces może zareagować na sygnały w sposób następujący:
Obsłużyć sygnał czyli wykonać funkcję dostarczoną poprzez programistę.
1.
Zignorować sygnał nie każdy sygnał daje się zignorować.
2.
Zablokować sygnał to znaczy odłożyć jego obsługę na pózniej.
3.
Zakończyć się po otrzymaniu sygnału.
4.
Reakcja procesu na sygnał w zależności od stanu w jakim znajduje się proces.
Gdy proces jest wykonywany lub gotowy to następuje przerwanie sekwencji
1.
wykonania i skok do procedury obsługi sygnału.
Gdy proces jest zablokowany to następuje jego odblokowanie i wykonanie
2.
procedury obsługi tego sygnału.
Instalacja handlera sygnału
Funkcje:
signal() (UNIX)
void(*signal(int sig, void(*func)(int)))(int))
gdzie sig to numer lub symbol sygnału, a func jest wskaznikiem na funkcję
która ma być wykonana. Nie można obsłużyć sygnałów SIGSTOP i SIGKILL.
Jako funkcję można podać SIG_IGN (ignore) lub SIG_DFL- domyślna reakcja
na sygnał (zakończenie lub zignorowanie)
sigaction() (POSIX)
int sigaction(int signo, struct sigaction *act, struct sigaction *oldact),
sigaction to struktura z informacjami o obsłudze sygnału:
struct sigaction {
void (*sa_handler)(int) ;
void(*sa_sigaction)(int signo,siginfo_t *info, void *inne)
sigset_t sa_mask; // Sygnały blok. podczas obsługi
int sa_flags; // Flagi modyfikacji działania
}
Dokładny opis parametrów: 13_Sygnaly.pdf strona 15
Blokowanie sygnałów
Blokada sygnałów
Podczas obsługi sygnału dostarczanie innych sygnałów jest zablokowane.
2. Sygnały i funkcje systemowe
W większości przypadków w czasie wykonania funkcji systemowych sygnały są
zablokowane. WyjÄ…tek stanowiÄ…:
- Funkcje read, write, open w odniesieniu do terminali.
- Funkcje wait, pause, sigsuspend
Funkcje te będą przerywane przez sygnał. Możliwe jest ustawienie flagi
SA_RESTART aby przerwane funkcje kontynuować.
Sygnały a wątki
Sygnały mogą być kierowane do procesów i do wątków.
Zachowanie się sygnałów w środowisku procesów wielowątkowych zdefiniowane
jest regułami:
1. Sygnały obsługiwane są na poziomie procesu. Znaczy to że gdy wątek zignoruje
lub obsłuży sygnał, fakt ten wpływa na inne wątki tego procesu.
2. Maskowanie sygnałów zachodzi na poziomie wątków.
3. Jeżeli sygnał skierowany jest do określonego wątku to będzie on do tego wątku
dostarczony.
4. Jeżeli sygnał skierowany jest do procesu to będzie dostarczony do pierwszego
wątku który nie blokuje danego sygnału.
Zasada obsługi sygnałów w środowiskach wielowątkowych:
Standardową strategią obsługi sygnałów w środowisku procesów wielowątkowych
jest zamaskowanie sygnałów we wszystkich watkach z wyjątkiem jednego. Ten
właśnie wątek będzie obsługiwał sygnały.
Timery
Timery - specjalne obiekty systemu operacyjnego, odpowiedzialne za generowanie
zdarzeń które w ustalonym czasie uruchomić mają określone akcje systemu.
Timery mogą wywoływać sygnał lub tworzyć nowy wątek, w zalezności o tego, co
wybierzemy w strukturze sigevent przekazywanej jako argument do funkcji tworzÄ…cej
nowy timer.
Posługiwanie się timerem
1. Tworzymy strukturę typu sigevent, w której wybieramy, co timer ma zrobić po
odliczeniu czasu (nowy wątek, sygnał itp),
2. Tworzymy timer za pomocÄ… timer_create()
3. Wybieramy sposób określenia czasu - absolutny lub relatywny (parametr funkcji
timer_settime())
4. Wybrać tryb pracy - jednorazowy lub cykliczny
W strukturze itimerspec mamy dwa pola - value, czyli czas, który musi upłynąć
przed pierwszą aktywacją timera, i interval, czyli czas pomiędzy kolejnymi
wywołaniami timera. Można ustawić interval na 0, co będzie skutkować
jednorazowÄ… aktywacjÄ… timera.
5. Nastawić timer, czyli wywołaś timer_settime() z odpowiednimi parametrami.
RPC
Zdalne wykonywanie procedur RPC
DO ZROBIENIA
Podstawowe pojęcia
Przetaczanie parametrów (ang. parameters marschalling) pakowanie parametrów
procedury do komunikatu z jednoczesnÄ… konwersjÄ… danych.
Przetaczanie parametrów obejmuje:
1. KonwersjÄ™ formatu komunikatu
2. SerializacjÄ™ danych
Namiastka klienta (ang. client stub) - reprezentuje serwer po stronie klienta
Namiastka serwera (ang. server stub) - reprezentuje klienta po stronie serwera
Synchroniczne RPC - klient czeka na odpowiedz serwera
Asynchroniczne RPC - klient przekazuje parametry do serwera i kontynuuje działanie.
Odroczone asynchroniczne RPC - klient przekazuje parametry do serwera i kontynuuje
działanie. Gdy serwer opracuje odpowiedz wywołuje procedurę po stronie klienta.
WiÄ…zanie dynamiczne
Przy zdalnym wywoływaniu procedur powstaje pytanie jak klient ma zlokalizować procedury
serwera.
WiÄ…zanie (ang. binding) odwzorowanie nazwy (procedury RPC) w konkretny obiekt
określony identyfikatorem komunikacyjnym. Postać identyfikatora zależy od systemu (np.
adres gniazdka - IP, port).
Aącznik (ang. binder) specjalna usługa RPC utrzymująca tablicę odwzorowań nazw usług
(procedur RPC) na porty serwerów tych usług. Aącznik utrzymywany jest przez serwery
które udostępniają identyfikatory portów swoim klientom. Od usług łącznika zależą wszystkie
inne usługi. Dlatego łączniki tworzy się tak aby tolerowały awarie. Np. tablice odwzorowań
zapisuje się w pliku z którego mogą być one wczytane w przypadku awarii.
Język opisu interfejsu IDL
DO ZROBIENIA
Tworzenie aplikacji w standardzie Sun RPC
Realizacja Sun RPC oparta jest na gniazdkach. Mechanizm gniazdek
jest zamaskowany przed użytkownikiem. Ma on do dyspozycji funkcje
wyższego poziomu.
Można korzystać z protokołu:
· TCP
· UDP (rozmiar danych ograniczony do 8 KB).
Dostępne trzy poziomy:
Poziom pierwszy - gotowych funkcji (np. nusers - liczba zal. użytk.)
Poziom pośredni łatwy w użyciu lecz ograniczona funkcjonalność
Poziom trzeci stosowane są funkcje niskiego poziomu, pełna funkcjonalność
Najczęściej stosowany jest poziom pośredni. Jest on odpowiedni dla
większości typowych aplikacji.
Aplikacja poziomu pośredniego nie umożliwia:
· Kontroli przeterminowaÅ„
· Użycie wielu procesów / wÄ…tków po stronie serwera
· Elastycznej obsÅ‚ugi bÅ‚Ä™dów
· Użycia zaawansowanej identyfikacji strony wywoÅ‚ujÄ…cej
Tworzenie aplikacji RPC odbywa się w następujących krokach:
1. Utworzenie interfejsu serwera specyfikacja (w języku opisu interfejsu RPCGEN )
co serwer ma wykonać i jak przekazuje się parametry.
2. Przy użyciu programu rpcgen generuje się namiastkę klienta (ang. client stub),
namiastkę serwera (ang. server stub), plik nagłówkowy, plik konwersji.
3. Implementacja usług serwerowych.
4. Implementacja aplikacji klienta wykorzystanie stopki klienta.
Program serwera działa według schematu:
1. Otrzymanie identyfikatora transportu (ang. transport handle)
2. Zarejestrowanie usługi u demona portmap
3. Oczekiwanie na zgłoszenia klienta i wykonywanie jego zleceń
Program klienta działa według schematu:
1. Otrzymanie identyfikatora klienta (ang. client handle)
2. Wywoływanie odległych procedur
3. Likwidacja identyfikatora klienta gdy nie jest potrzebny
Linda
System Linda
System Linda jest oryginalnym i zarazem mocną koncepcją tworzenia systemów
współbieżnych i równoległych. Linda nie jest samodzielnym językiem programowania ale
dodatkiem do innych języków. A więc istnieje C-Linda, FORTRAN-Linda i inne. Koncepcyjnie
Linda jest prosta a fakt że stanowi ona dodatek do znanego już języka (nie trzeba się uczyć
od początku) podnosi jej atrakcyjność. Linda bazuje na koncepcji pamięci dzielonej (być
może rozproszonej) nazywanej przestrzenią krotek TS (ang. Tuple Space) i niewielkiej
liczbie operacji zapewniającej dostęp do tej przestrzeni, synchronizację i wzajemną
komunikację procesów współbieżnych. Koncepcja Lindy wspiera model programowania
równoległego znany jako zarządca wykonawca (ang. Worker Manager). Koncepcja
systemu pochodzi od Davida Gelerntera z Yale University. Linda jest językiem opisującym
koordynację (ang. cordination language) (synchronizację i komunikację) procesów.
Linda własności
Wspiera tworzenie aplikacji równoległych typu zarządca wykonawca
Kod niezależny od liczby procesów wykonawczych
Wspiera równoległość i komunikację międzyprocesową
Nakładanie się komunikacji i obliczeń
Nadaje się do systemów heterogenicznych (składających się z różnych maszyn)
Przestrzeń krotek
Przestrzeń krotek TS jest abstrakcją zawierającą posiadające typy ciągi danych. Przestrzeń
krotek jest globalna w całym systemie chociaż może być implementowana na maszynach z
rozproszoną pamięcią dzieloną.
Przestrzeń krotek dzielona przestrzeń danych.
Krotka lista do 16 pól zawierających dane języka bazowego. Pola te są rozdzielone
przecinkami. W języku C-Linda pola mogą być znakami, łańcuchami, typu całkowitego,
rzeczywistego lub typami złożonymi jak tablice lub struktury ale nie zawierające krotek.
Przykłady krotek:
( dane1 , 13, 2)
(x1, x2)
( zadanie1 ,i,j)
Przestrzeń krotek oparta jest na pamięci asocjacyjnej.
· DostÄ™p do krotek opiera siÄ™ na ich zawartoÅ›ci
· Krotki nie posiadajÄ… adresu przez który można by do nich siÄ™gnąć.
Krotki mogą zawierać dwie kategorie danych:
· Parametry rzeczywiste (ang. actual parameters) zawierajÄ… ustalone dane pewnego typu.
· Parametry formalne (ang. formal parameters) sÄ… pojemnikiem na dane pewnego typu.
Krotki dziurawe
Krotki zawierajÄ…ce parametr formalny nazywane sÄ… krotkami dziurawymi.
Znak ? oznacza że jest to parametr formalny. Ma on typ ale nie posiada wartości.
Przykład:
("rzeczywisty", ",formalny",? x) x jest zmiennÄ… typu int
Krotki pasywne i aktywne.
· Krotki mogÄ… być pasywne lub aktywne.
· Krotka pasywna zawiera ustalone dane.
· Krotka aktywna zawiera przynajmniej jeden parametr którego wartość nie jest jeszcze
ustalona. Taki nieustalony parametr jest funkcjÄ…. Gdy krotka aktywna umieszczana jest w
przestrzeni krotek system tworzy współbieżny proces który oblicza jej wartość.
· Po obliczeniu wartoÅ›ci wynik jest wstawiany do krotki i krotka staje siÄ™ pasywna.
Przykład:
("test", i, f(i));
Operacje
out Umieszczenie krotki pasywnej w TS
eval Umieszczenie krotki aktywnej w TS
in Pobranie krotki z TS wersja blokujÄ…ca
inp Pobranie krotki z TS wersja nieblokujÄ…ca
rd Odczyt krotki z TS wersja blokujÄ…ca
rdp Odczyt krotki z TS wersja nieblokujÄ…ca
Wyrażanie operacji synchronizacyjnych i
komunikacyjnych
DO ZROBIENIA
Problem producenta i konsumenta,
czytelników i pisarzy
Rozwiązanie za pomocą semaforów
DO ZROBIENIA
Rozwiązanie za pomocą monitorów
DO ZROBIENIA
RozwiÄ…zanie za pomocÄ… zmiennych warunkowych
DO ZROBIENIA
Rozwiązanie za pomocą mechanizmów języka Linda
DO ZROBIENIA
Wyszukiwarka
Podobne podstrony:
opracowanie zagadnień na bazymechanika plynow opracowanie zagadnienstasieńko,wytrzymalosc I, opracowanie zagadnień na egzEkonomia Rozwoju Garbicz Opracowanie zagadnień do egzaminuOpracowanie Teoria?zy?nych 11 Plebs By ITCompozerANTROPOLOGIA KULTROWA opracowanie zagadnień[ASK] Opracowanie zagadnień na egzamin w trakcie składaniabiłyk,Chemia wody, opracowanie zagadnieńOpracowanie zagadnień egzaminacyjnych z dób średniopolskiej i nowopolskiejBiochemia opracowanie zagadnieńOpracowanie Zagadnień na egzamin Mikroprockiwik opracowane zagadnieniaZagadnienie 11,12Hoffmann, zarządzanie jakością, Opracowanie zagadnie systemy zarzadzania jakosciaOpracowane zagadnienia wykładJasiorski, chemia ogólna, Opracowane zagadninia na kolowiumwięcej podobnych podstron