580 likes | 724 Views
Systemy rozproszone – Procesy przygotowanie: Marcin Zacharski. 1. Wątki 2. Klienci 3. Serwery 4. Migracja kodu 5. Agenci programowi. Proces – obiekt aktywny. Zawiera licznik rozkazów do wykonania i zbiór przydzielonych zasobów składających się z: - kodu programu (sekcja tekstu)
E N D
Systemy rozproszone – Procesyprzygotowanie: Marcin Zacharski 1. Wątki 2. Klienci 3. Serwery 4. Migracja kodu 5. Agenci programowi
Proces – obiekt aktywny. Zawiera licznik rozkazów do wykonania i zbiór przydzielonych zasobów składających się z: - kodu programu (sekcja tekstu) - odpowiednio ustawionego licznika rozkazów - zawartości rejestrów procesora - stosu procesu: parametry procedur, adresy powrotu, zmienne tymczasowe - sekcji danych: zmienne globalne Zarządca procesów (process manager) — kontroluje stany procesów w celu efektywnego i bezpiecznego wykorzystania współdzielonych zasobów systemu. Zarządca zasobów (resource manager) — realizuje przydział zasobów stosownie do żądań procesów, aktualnego stanu systemu oraz ogólnosystemowej polityki przydziału. Agenci programowi - W aplikacji typu klient-serwer proces pośredniczący między klientem a serwerem. - Autonomiczna jednostka programową zdolna do interakcji w swoim środowisku (zwłaszcza z innymi agentami).
Tworzenie procesu – System operacyjny tworzy przestrzeń adresową dla procesu oraz strukturę opisującą nowy proces w następujący sposób: wypełnia strukturę opisującą proces, kopiuje do przestrzeni adresowej procesu dane i kod zawarte w pliku wykonywalnym, ustawia stan procesu na działający, dołącza nowy proces do kolejki procesów oczekujących na procesor (ustala jego priorytet) Kosztowne przełączanie CPU - Przełączanie procesora do innego procesu wymaga przechowania stanu starego procesu i załadowania przechowanego stanu nowego procesu – przełączanie kontekstu (contextswitch). System nie wykonuje żadnej użytecznej pracy podczas tej czynności. Wartość czasu przełączania zależy od możliwości sprzętu. Niektóre procesory mają po kilka zbiorów rejestrów: przełączanie kontekstu – zmiana wartości wskaźnika do bieżącego zbioru rejestrów. Przełączanie kontekstu jest nierzadko „wąskim gardłem” w systemach operacyjnych. Rozwiązanie: wątki.
Szybkie przełączanie – należy do zalet wątków: Dzielenie zasobów sprawia, ze przełączanie miedzy wątkami oraz tworzenie jest tanie w porównaniu z procesami ciężkimi. Oszczędne wykorzystanie zasobów – dzięki ich współużytkowaniu. Współpraca wielu wątków pozwala zwiększyć przepustowość i poprawić wydajność (np. jeśli jeden wątek jest zablokowany, to może działać inny). Lepsze wykorzystanie architektury wieloprocesorowej/wielordzeniowej (wątek procesor/rdzeń) oraz dedykowanej technologii Hyper-Threading. (jest to implementacja wielowątkowości współbieżnej). Hyper-threading służy zwiększeniu wydajności obliczeń prowadzonych równolegle (czyli wykonywaniu wielu zadań jednocześnie) przez mikroprocesory. Dla każdego fizycznego rdzenia procesora system operacyjny przypisuje dwa procesory wirtualne (ang. virtualprocessors), a następnie dzieli obciążenie obliczeniami między nimi jeżeli jest to możliwe. Hyper-threading wymaga nie tylko wsparcia ze strony systemu operacyjnego ale również oprogramowania specyficznie zoptymalizowanego dla obsługi tej technologii, Intel zaleca wyłączanie jej jeżeli używany jest system operacyjny bez takich optymalizacji. wykorzystanie równoległości w systemach wieloprocesorowych – każdy watek ma swój procesor i przydzielone swoje zasoby
- znacznie szybsze mechanizmy „IPC” - Bufor może być dostarczony przez system operacyjny za pomocą mechanizmu komunikacji międzyprocesowej (IPC) lub stworzony przez programistę w pamięci dzielonej. Umożliwia procesom łączność i komunikację.
Dostarcza dwie operacje: nadaj (komunikat) i odbierz (komunikat). Jeżeli procesy chcą się między sobą komunikować to musza utworzyć miedzy sobą łącze komunikacyjne i wymieniać komunikaty. Wykonanie może być fizyczne (pamięć dzielona, szyna sprzętowa, sieć) lub logiczne (cechy łącza) Komunikacja międzyprocesowa (ang. Inter-ProcessCommunication — IPC) – umowna nazwa zbioru sposobów komunikacji pomiędzy procesami systemu operacyjnego. Procesy mogą używać różnych sposobów komunikacji, a najpowszechniejsze z nich to: - pliki i blokady – najprostsza i najstarsza forma IPC - sygnały (ang. signals) – w niektórych systemach (jak np. DOS) znane jako przerwania programowe - semafory (ang. semaphores) - łącza nienazwane (ang. pipes) – znane też jako łącza komunikacyjne - łącza nazwane (ang. namedpipes) – znane też jako nazwane łącza komunikacyjne - kolejki komunikatów (ang. messagequeues) - pamięć dzieloną (ang. sharedmemory) – znane też jako segmenty pamięci dzielonej (ang. sharedmemorysegments) - gniazda dziedziny Uniksa (ang. Unix domainsockets)
Wątek (ang. thread) jest definiowany często jako podstawowa jednostka wykorzystania procesora. Wątki można przedstawić jako fragmenty większej całości, jaką jest proces. Wątki współdzielą pewne zasoby charakterystyczne dla procesu tj.: sekcję kodu, sekcję danych, sygnały, otwarte pliki itp. Jeżeli teraz weźmiemy grupę wątków, z których każdy reprezentuje pewną sekwencję operacji do wykonania, i umieścimy je w ramach jednego procesu, możemy przełączać wątki nie przełączając procesu. Ilość informacji potrzebna do utrzymania wątku jest mniejsza ze względu na współdzielone dane między wątkami tego samego procesu, tym samym przełączanie kontekstu wątków jest znacznie szybsze od przełączania kontekstu procesów. Omówione wątki funkcjonują na poziomie jądra (ang. kernelmode) systemu operacyjnego; są nazywane również procesem lekkim (ang. Lightweightprocess –LWP). Obok nich mogą również występować wątki poziomu użytkownika. Wątki poziomu użytkownika działają całkowicie w przestrzeni użytkownika (ang. usermode). Ich głównymi zaletami jest mały koszt tworzenia i usuwania oraz mały koszt przełączania kontekstu. Wadą jest blokada całego procesu w przypadku wywołań systemowych. W tym wypadku z pomocą przychodzą bardziej kosztowne w utrzymaniu wątki poziomu jądra. UWAGA. W terminologii procesów wyróżnia się specjalny przypadek jednowątkowego procesu tzw. procesu ciężkiego (ang. heavyweightprocess).
Minusem modelu przetwarzania z wątkami jest m.in. konieczność dbania programisty o bezpieczeństwo dostępu do dzielonych między wątki danych, co realizowane jest za pomocą semaforów itp. W zamian jednakże otrzymujemy wiele korzyści, a wśród nich m.in.: zwiększenie efektywności przy obsłudze wielu współbieżnych zadań, możliwość wykonywania równoległych wątków na wielu procesorach ze wspólną, dzieloną pamięcią. Wielowątkowość spowodowała również pewien przełom w podejściu do projektowania aplikacji. Zaczęto je m.in. dzielić na wiele mniejszych współpracujących ze sobą części. To z kolei uprościło i usystematyzowało niektóre aspekty budowania programów. Mutex jest mechanizmem wzajemnego wykluczania (MUTual EXclusion) służącym do chronienia danych dzielonych miedzy watkami przed równoczesnymi modyfikacjami i używanym do implementacji sekcji krytycznych i monitorów. Mutex ma dwa możliwe stany: otwarty (nie zajęty przez żaden watek) lub zajęty (przez jeden watek). Mutex nie może być w posiadaniu więcej niż jednego wątku na raz. Watek próbujący zając mutex będący w posiadaniu innego wątku jest zawieszany aż do chwili zwolnienia mutexu przez watek, który go posiadał wcześniej.
Aktywacja planisty Realizacja wątków przez odpowiednią bibliotekę w trybie użytkownika zwiększa szybkość przełączania kontekstu, ale powoduje, że jądro, nie wiedząc nic o wątkach, planuje przydział czasu procesora dla procesów. Oznacza to, że w przypadku większej liczby wątków procesu czas procesora, przypadający na jeden wątek jest mniejszy, niż w przypadku procesu z mniejszą liczbą wątków. Problemem jest też wprowadzanie procesu w stan oczekiwania, gdy jeden z wątków zażąda operacji wejścia-wyjścia lub utknie na jakimś mechanizmie synchronizacji z innymi procesami. Planista traktuje taki proces jako oczekujący do czasu zakończenia operacji, podczas gdy inne wątki, o których jądro nie wie, mogłyby się wykonywać.
Serwery Wielowątkowe PRZEZROCZYSTOŚĆ: Definiuje się jako ukrywanie przed użytkownikiem i programistą aplikacji oddzielności składowych w systemie rozproszonym, tak że system jest postrzegany jako całość , a nie jako zbiór niezależnych składowych. Ogólnie mówiąc jest to ukrycie rozproszenia oraz złożoności systemu operacyjnego przed użytkownikami. Wyróżniamy następujące dziedziny przezroczystości: położenia: użytkownicy nie mogą bo nie muszą określić lokalizacji zasobów. wędrówki: zasoby mogą być przemieszczane bez zmiany nazw. zwielokrotniania: użytkownicy nie mogą określić liczby istniejących kopii. współbieżności: automatyczne dzielenie zasobów między użytkowników - dokonywane współbieżnie, a nie sekwencyjnie. działań równoległych: zadania są wykonywane równolegle bez wiedzy użytkowników
Serwer wielowątkowy Serwer wielowątkowy - w modelu dispatcher/worker - w tym rozwiązaniu wyróżnia się wątek zawiadowcy (dispatcherthread) obsługujący wątki robocze (workerthread). Watki robocze korzystają z pamięci buforowej współdzielonej (sharedblockcache). Proces zawiadowcy korzysta ze skrzynki pocztowej, do której wpisywane są zadania dotyczące operacji dyskowej. Zawiadowca czyta ze skrzynki pocztowej zgłaszane do serwera zgłoszenie. Następnie wybiera bezczynny watek roboczy i przekazuje mu żądanie. Konkretnie zapisuje on wskaźnik do komunikatu z żądaniem do specjalnego słowa związanego z danym wątkiem roboczym. Do budzenia wątków roboczych najczęściej stosowane są operacje semaforowe. Wątek roboczy sprawdza wpierw, czy żądanie może zostać wykonane na podstawie danych znajdujących się aktualnie we współdzielonej pamięci buforowej.
Modele Serwerów wielowątkowych Model Zespołowy (Team Model) - jest to inna realizacja procesu serwera. Wszystkie wątki są tutaj równoważne. Każdy może pobierać i realizować żądania przy czym mogą być specjalizowane do pewnych zadań. Niezbędne jest zatem utrzymywanie informacji o żądaniach aktualnie realizowanych - najczęściej w formie kolejki żądań. Wątek, zanim pobierze ze skrzynki pocztowej zlecenie do wykonania, musi najpierw sprawdzić tę kolejkę Model Potokowy (Pipeline Model) - w tym modelu zlecone zadanie jest przydzielane do pierwszego wątku w potoku, a następnie jest przekazywane od jednego wątku do drugiego. Każdy z wątków częściowo przetwarza przechodzące przez niego dane. To rozwiązanie nadaje się do implementacji producenta i konsumenta ale nie nadaje się do realizacji serwera plików
Maszyna stanów skończonych jest pojęciem abstrakcyjnym i definiuje zachowanie systemów dynamicznych jako maszyny o skończonej liczbie stanów i skończonej liczbie przejść pomiędzy tymi stanami. Definicja ta może wydawać się dość abstrakcyjna dla typowego programisty, jednak jak się przekonamy, maszyny stanów skończonych odgrywają bardzo ważną rolę w programowaniu mikroprocesorów. Trzy sposoby budowy serwera - Model i charakterystyka Wątki - Zwiększenie stopnia równoległości lecz nadal są obecne funkcje powodujące blokadę wątków. Proces jednowątkowy - brak współbieżności; obecność funkcji systemowych mogących zablokować wątki. Maszyna końcowa - Implementacja serwera plików na dużym komputerze, gdzie wydzielony proces bada nadchodzące żądania. Do dysku wysyłany jest odpowiedni komunikat z zadaniem obsługi żądania (jeśli brak tych danych w pamięci buforowej). Po wysłaniu komunikatu do dysku proces nie jest blokowany. Zapisuje on stan żądania do specjalnej tablicy systemowej i przechodzi do obsługi następnego żądania. Generalnie wątki podtrzymują ideę procesów sekwencyjnych gdzie wywołania systemowe są blokujące, ale osiąga się równoległość.
System X - Window Podstawowe pojęcia i architektura sytemu X – Window, składniki sytemu X - Window serwery ekranowe - urządzenia użytkownika takie jak ekran, klawiatura, mysz klienci - programy wyświetlające protokół x komunikacji klientów z serwerami Rola serwera X - Window: - obsługa zdarzeń serwera, tzn. odbieranie sygnałów od myszy i z klawiatury oraz przekazywanie ich klientowi aktywnemu (focus), a także odbieranie poleceń i zapytań klientów i ich realizacja. - uruchamianie serwera X window: X, xinit, startx albo automatycznie przez xdm, razem z procesem włączania użytkownika do systemu (login, hasło) i uruchamianie (odtwarzanie) sesji użytkownika - konfigurowanie pracującego serwera: xset, xsetroot, xrdb, xmodmap
System X - Window xinit jest używany do startu systemu X Window i pierwszego programu klienta dla systemów, które nie mogą wystartować X wprost z katalogu /etc/init albo w środowisku które używa wielu systemów okien. Kiedy pierwszy klient istnieje, xinit będzie kończył proces X serwera i ten się zakończy. xdm (X Window Display Manager) - domyślny menedżer logowania w X11 w systemach unixowych. Został po raz pierwszy wprowadzony w październiku 1988 w wydaniu trzecim X11. startx - jest interfejsem do programu xinit, który dostarcza przyjaznej obsługi użytkownika dla uruchamiania pojedynczej sesji systemu X Window. Jest wywoływany zwykle bez argumentów.
Klienty X - Window - połączenie klientów z serwerem: o ile serwer normalnie komunikuje się z wieloma klientami jednocześnie obsługując ich żądania, to każdy klient wysyła dane do wyświetlania do jednego konkretnego serwera - do wyświetlania informacji i komunikacji z użytkownikiem służą klientom okienka na ekranie, a także inne "urządzenia" tzw. widgets, pop-up menu, "radio-button", "scroll-bar", oraz oczywiście mysz i klawiatura - zdarzenie klienta: sygnały z klawiatury, od myszy, a także inne zdarzenia przekazywane przez serwer, np: zdarzenie odsłonięcia - przykładowe klienty: xclock, xload, xmag, xterm (klawisze myszy); inne klienty: netscape, emacs, xv, ghostscript - opcje wywołania klientów mogą określać: adres serwera: -display adres-ip:0.0 geometrie: -geometry szeXwys+xoff kolory: -fgyellow -bgblue -bd red inne parametry: -title xxx -fn -iconic
Oprogramowanie klienckie dla przezroczystości rozproszenia Przezroczystość w systemach rozproszonych - Komponent rozproszony jest nazywany przezroczystym, gdy jest niewidoczny dla użytkownika, programistów aplikacji lub administratorów. W rozproszonych systemach fakt złożoności systemów z dużej liczby komponentów powinien być ukryty przed użytkownikami. Oni pracują na systemie tak, jakby był on pojedynczym komputerem. Przezroczystość dostępu - wymaga, aby interfejsy żądań usługi były takie same dla komunikacji pomiędzy komponentami jednego hosta oraz różnych hostów (oznacza to identyczność interfejsów w komunikacji lokalnej i rozległej). Przezroczystość lokalizacji - wymaga, aby w odniesieniu do identyfikacji komponentów, żądanie usługi nie posiadało informacji, gdzie wymagany komponent (host) jest fizycznie zlokalizowany.
Przezroczystość przenaszalności - oznacza , że komponent może być przeniesiony z jednego hosta na drugi w sposób niedostrzegalny dla użytkowników i klientów. Takie przeniesienie jest nazywane przezroczystością migracji. Ponadto użytkownik nie musi ingerować w proces przenoszenia. Przezroczystość awarii: Umożliwienie nieprzerwanej pracy większości użytkowników rozproszonej bazy danych w sytuacji, gdy niektóre z jej węzłów lub linie komunikacyjne uległy awarii Przezroczystość błędów - użytkownicy i programiści nie wiedzą w jaki sposób system przezwycięża błędy. Przenaszalność (portability) Własność języka programowania i jego kompilatorów/interpreterów umożliwiająca przenoszenie programów na różne platformy. Przezroczystość współbieżnego wykonywania - kilka komponentów może wywołać usługę jednocześnie odwołując się do dzielonych składników, zachowując ich integralność. Żaden z projektantów ani użytkowników nie powinien widzieć wewnętrznej organizacji systemu współbieżnego.
Monitory transakcyjne Monitory transakcyjne, jako już ponad trzydziestoletnia architektura, miała za zadanie stworzenie środowiska, prawie systemu operacyjnego, dla aplikacji biznesowych. Podobnie jak systemy operacyjne zarządzają procesami, współdzieleniem zasobów czy pamięcią, tak monitory transakcyjne zarządzają m.in. wielodostępem, transakcyjnością oraz dostępem do baz danych. Podobnie jak twórca aplikacji pracującej pod kontrolą systemu operacyjnego nie martwi się w jaki sposób wywłaszczana jest pamięć, podobnie twórca aplikacji zarządzanej przez monitor transakcyjny nie przejmuje się, w jaki sposób transakcja czy wielodostęp są zrealizowane. Oba środowiska uruchomieniowe wypełniają swoje zadania automatycznie pozostawiając programistom jedynie troskę o zapewnienie funkcjonalności biznesowej.
Serwery – zagadnienia projektowe Serwer iteracyjny samodzielnie obsługuje zlecenia klientów zwracając im ewentualnie wyniki. Innymi słowy serwer zmuszony jest do obsługi zleceń jedno po drugim, przy czym zanim rozpocznie kolejne zadanie musi zakończyć wykonywanie poprzedniego. Serwer współbieżny pozbawiony jest niedogodności powodującej, że każde kolejne żądanie musi oczekiwać w kolejce do momentu gdy zostaną obsłużone poprzednie. W tym przypadku serwer po odebraniu zlecenia od klienta przekazuje wykonanie zlecenia innemu wątkowi lub procesowi. Po tym jak przekaże zlecenie może natychmiast przystąpić do obsługi innych zleceń. Z architekturą serwerów współbieżnych wiąże się m.in. kwestia miejsca kontaktowego z serwerem. Miejscem takim jest zazwyczaj pewien dobrze znany wszystkim klientom port (tzw. punkt końcowy –ang. endpoint). Po skontaktowaniu się klienta przez taki port z serwerem klient otrzymuje np. nowy port do komunikacji z procesem obsługującym jego zlecenie, tym samym zwalnia punkt końcowy na rzecz nowych klientów serwera. Kolejnym kryterium według którego możemy dzielić serwery jest kwestia obsługi stanu. Wyróżniamy mianowicie: serwery bezstanowe (ang. statelessserver) oraz serwery pełno-stanowe (ang. State ful server).
Serwery – zagadnienia projektowe Serwer współbieżny – serwer zdolny do współbieżnej obsługi zleceń wielu klientów. Składa się z pewnej liczby procesów lub wątków realizujących zlecenia klientów. Serwer stanowy (ang. Statefulserver) – serwer przechowuje informacje o kliencie. Są dwa typy informacji przechowywanej przez serwer: - Informacja globalna - Informacja o stanie sesji
Serwer bezstanowy Serwer bezstanowy charakteryzuje się głównie tym, że nie przechowuje danych o swoich klientach. Również zmiana stanu samego serwera niekoniecznie wpływa na zmianę stanu jego klientów. Przykładem może być tu prosty serwer plików lub serwer sieci. Przeciwieństwem serwera bezstanowego jest serwer pełno stanowy, który przechowuje informacje o swoich klientach np. w celu odesłania im w przyszłości jakichś danych. Również tutaj za przykład może posłużyć rozproszony systemem plików, tym razem jednak taki, który przechowuje informacje o klientach w celu zapewnienia im w przyszłości szybszego dostępu do danych. Zasadniczą niedogodnością w przypadku serwerów pełno stanowych są awarie, które powodują utratę stanu i wymuszają konieczność jego odtwarzania.
Serwery internetowe i ciasteczka Serwer internetowy - to inaczej komputer świadczący określonemu użytkownikowi odpowiednią usługę np. udostępnianie wiadomości e-mail lub określonej strony WWW. Ciasteczka (ang. cookies) to niewielkie informacje tekstowe, wysyłane przez serwer WWW i zapisywane po stronie użytkownika (zazwyczaj na twardym dysku). Domyślne parametry ciasteczek pozwalają na odczytanie informacji w nich zawartych jedynie serwerowi, który je utworzył. Ciasteczka są stosowane najczęściej w przypadku liczników, sond, sklepów internetowych, stron wymagających logowania, reklam i do monitorowania aktywności odwiedzających. Mogą zawierać rozmaite rodzaje informacji o użytkowniku danej strony WWW i "historii" jego łączności z daną stroną (a właściwie serwerem). Zazwyczaj wykorzystywane są do automatycznego rozpoznawania danego użytkownika przez serwer, dzięki czemu może on wygenerować przeznaczoną dla niego stronę. Umożliwia to tworzenie spersonalizowanych serwisów WWW, obsługi logowania, "koszyków zakupowych" w internetowych sklepach itp.
Serwery: zagadnienia projektowe Wiązanie klienta z serwerem: Wiązanie statyczne —klient ma na stałe wprowadzony identyfikator komunikacyjny serwera (np. para: adres IP, nr portu). Wiązanie dynamiczne — klient uzyskuje adres serwera za pośrednictwem łącznika (np. portmap, lub rpcbind w Sun RPC). Interfejs DCE RPC identyfikowany jest przez jednoznaczny identyfikator UID, składający się ze 128 bitowej liczby dwójkowej. Identyfikatory UID generowane są przez generator uuidgen, na podstawie informacji o lokalizacji komputera oraz czasu. Wiązanie w DCE RPC ma charakter lokalny, tzn. środowisko utrzymuje na maszynie serwera proces zwany demonem DCE (DCEdaemon), wykonujący usługę odwzorowania portów. Środowisko DCE dostarcza jednak również globalnych usług wiązania. Serwer RPC może zostać zarejestrowany w globalnej usłudze katalogowej.
a) Wiązanie klient-serwer z użyciem demona jak w DCEb) wiązanie klient-serwer z użyciem super serwera jak w Unix-e
Serwery obiektów – Adapter obiektów Ogólnie rozumiany serwer obiektowy (ang. objectserver) jest środowiskiem do przechowywania i zarządzania obiektami, także tymi rozproszonymi. Każdy obiekt posiada pewien kod, w postaci zaimplementowanych metod, oraz stan w postaci danych. Sposób zarządzania tymi obiema częściami zależy w dużej mierze od serwera obiektowego, którego implementacja określa np. to ile wątków ma działać w ramach jednego obiektu, czy dla każdego wywołania ma być używany osobny wątek, czy obiekty powinny mieć dostęp do wspólnych segmentów pamięci itp.
Serwery obiektów - Adapter obiektów (2) Polityka aktywacji - decyzja jak wywołać obiekt, - obiekt musi być najpierw umieszczony w przestrzeni adresowej serwera (tj., najpierw aktywowany, następnie wywoływany) - adaptery obiektów nieświadome specyficznych interfejsów obiektów, które kontrolują, - żądania nie są przekazywane od razu do obiektów, - adapter dostarcza hands żądanie wywołania do stub’u obiektu po stronie serwera. Przykład oczekiwanej operacji adaptera obiektów implementowanej przez każdy skeleton specyficzny dla obiektu: - invoke( unsignedin_size, char in_args[], unsigned* out_size, char* out_args[]) Rejestracja obiektu: przekazuje wskaźnik do specyficznej dla obiektu implementacji procedury invoke, zwraca id obiektu względem adaptera.
Serwery obiektów - Adapter obiektów (2) Najprostszym sposobem realizacji serwera obiektowego jest użycie jednego wątku sterowania. Innym podejściem jest zastosowanie kilku wątków, w ten sposób aby każdy obiekt miał własny wątek. W tym rozwiązaniu serwer po otrzymaniu zlecenia przekazuje je po prostu do odpowiedniego wątku, który jeśli jest zajęty w danej chwili, odkłada je na pewien czas do kolejki. Kolejnym podejściem jest zastosowanie osobnych wątków do każdego zamówienia. Wszystkie te rozwiązania sprowadzają się do wyboru pomiędzy tworzeniem wątków na żądanie a przechowywaniem pewnej liczby wątków. Z serwerem obiektowym wiąże się pojęcie adaptera obiektu (ang. Object adapter). W skrócie można opisać go jako implementację pewnej polityki uaktywniania (ang. activationpolicies) danego obiektu. Serwer obiektowy, w miarę potrzeby powinien mieć możliwość udostępniania różnej polityki uaktywnień wobec różnych obiektów, czyli powinien posiadać różne adaptery obiektów. Zamówienia, które przychodzą do takiego serwera są po prostu kierowane przez specjalny demultiplekser do odpowiedniego adaptera obiektu. Należy zaznaczyć, że adaptery obiektów nie muszą znać interfejsów obiektów, które obsługują.
Adapter obiektu – kod źródłowy /* Definitions needed by caller of adapter and adapter */#define TRUE#define MAX_DATA 65536 /* Definition of general message format */struct message { long source /* senders identity */ long object_id; /* identifier for the requested object */ long method_id; /* identifier for the requested method */ unsigned size; /* total bytes in list of parameters */ char **data; /* parameters as sequence of bytes */}; /* General definition of operation to be called at skeleton of object */typedef void (*METHOD_CALL)(unsigned, char* unsigned*, char**); long register_object (METHOD_CALL call); /* register an object */void unrigester_object (long object_id); /* unregister an object */void invoke_adapter (message *request); /* call the adapter */ Plikheader.hużywany przez adapter i dowolny program wywołujący ten adapter.
Adapter obiektu. Plikthread.hwykorzystywany przez adapterza pomocą wątków. typedefstruct thread THREAD;/* hidden definition of a thread */ thread *CREATE_THREAD (void (*body)(long tid), long thread_id);/* Create a thread by giving a pointer to a function that defines the actual *//* behavior of the thread, along with a thread identifier */ void get_msg (unsigned *size, char **data);void put_msg(THREAD *receiver, unsigned size, char **data);/* Calling get_msg blocks the thread until of a message has been put into its *//* associated buffer. Putting a message in a thread's buffer is a nonblocking *//* operation. */
Główna częśćadapteraktóry implementujepolitykęwątek-na-obiekt
Przyczyny migracji kodu Zasada dynamicznego konfigurowaniaklientado komunikacjizserwerem. Klientnajpierw ściąga potrzebne oprogramowanie, i następnie wywołuje serwer.
Wędrówka procesów (1) • Wędrówka procesów daje możliwość przemieszczania procesów w trakcie ich wykonywania z jednego procesora na inny • Problemy: – ustalenie stanu procesu: stan wewnętrzny, lokalna kolejka komunikatów, stan komunikacji ze zdalnymi procesami – transparentność wędrówki – obsługa przyszłej komunikacji – kiedy zdalnie wykonywać proces
Wędrówka procesów (2) Wędrówka kodu (ang. codemigration), sprowadza się w dużej mierze do wędrówki pewnych danych. Jednakże, wędrówka kodu to niejednokrotnie coś więcej niż przesyłanie samych danych, a mianowicie związana z nią wędrówka procesu (migracja procesów –ang. processmigration). Ponieważ jak wiadomo, procesy mogą być aktywne i są z nimi związane pewne zasoby, problem wędrówki procesu jest o wiele bardziej skomplikowany niż wędrówka samych danych. Koszt takiej operacji jest zazwyczaj stosunkowy duży. Mimo to, właśnie efektywność jest główną przyczyną dla której wykonuje się przeniesienia procesów. Jako przykład niech posłuży sieć komputerów, które wykonują pewne czasochłonne obliczenia. Część z nich może być mniej obciążona od innych. W celu poprawy globalnej efektywności przetwarzania przenosimy część obliczeń z komputerów bardziej obciążonych na te mniej obciążone. Praktyczna realizacja tej koncepcji wymaga jednak odpowiedzi na wiele szczegółowych pytań. Jak stwierdzić które z komputerów są mniej obciążone? Jaki jest algorytm według, którego procesy są przydzielane lub przenoszone na odpowiednie komputery? Co zrobić gdy środowisko maszyn jest heterogeniczne?
Migracja kodu (1) • Platforma: proces składa się z trzech segmentów: • segment kodu, • segment zasobów (referencje do zewnętrznych zasobów), • segment wykonania (bieżący stan wykonania). Wiązanie z zasobami: • przez id – np. URL, • przez wartość– gdy program bazuje na standardowych bibliotekach (C, Java), • przez typ – referencje do lokalnych urządzeń np.. monitory, drukarki. Słaba (weak) mobilność – możliwy do przeniesienia segment kodu z częścią inicjalizacyjną, Silna (strong) mobilność – mogą być przeniesione segmenty kodu i wykonania
Migracja kodu (2) Wraz z wędrówką procesu pojawia się problem zarządzania zasobami lokalnymi, z których korzysta przenoszony proces. Sposób postępowania z zasobami lokalnymi zależy od kilku czynników. Jednym z nich jest sposób w jaki proces jest związany z danym zasobem. Wyróżniono zasadniczo trzy sposoby wiązania zasobów: wiązanie przez identyfikator (ang. bindingbyidentifier), wiązanie przez wartość (ang. bindingbyvalue) i wiązanie przez typ (ang. bindingbytype). Proces, który odwołuje się do zasobu przez identyfikator oczekuje konkretnego zasobu o danym identyfikatorze, czyli np. adresie internetowym. Jest to najmocniejsza forma wiązania. Słabszą formą związania zasobu jest wiązanie przez wartość. Taki typ wiązania powoduje, że proces odwołuje się do wartości zasobu, a nie do konkretnego zasobu. Ostatnim, najmniej wymagającym typem wiązania, jest wiązanie przez typ, w którym wymaga się dostępu do zasobu o określonym typie.
Migracja kodu (3) Operacja przenoszenia procesu z jednej maszyny na drugą może przybierać wiele postaci. Oprócz wędrówki kodu możemy mieć tu do czynienia z koniecznością przeniesienia stanu procesu, który jest w trakcie wykonywania. Dla uproszczenia rozważań o modelach załóżmy, że każdy proces składa się z trzech segmentów: segmentu kodu, segmentu zasobów oraz segmentu wykonania (ang. executionsegment), który przechowuje dane o bieżącym stanie procesu. W najprostszym przypadku będziemy mieli do czynienia z przenośnością słabą (ang. weakmobility). W tym przypadku przesyłany jest tylko segment kodu. Jeżeli dodamy tego możliwość przesyłania segmentu wykonania uzyskamy tzw. przenośność silną (ang. strongmobility). Przenośność silna jest ogólniejsza od słabej i pozwala na przenoszenie procesów w trakcie ich wykonywania. Wadą przenośności silnej jest jednak jej większa złożoność. Przenośność słabą można jeszcze rozróżnić w zależności od tego czy w celu wykonania przesłanego kodu uruchamiany jest nowy proces na maszynie docelowej, czy też kod ten wykonywany jest w ramach pewnego procesu docelowego. W wypadku przenośności silnej wyróżnia się metodę klonowania procesów, która polega na skopiowaniu działającego programu na docelową maszynę w taki sposób, że oryginał i jego kopia działają równolegle.
Migracja kodu (4) Kolejną kwestią wymagającą rozpatrzenia jest wybór inicjatora wędrówki. Jeżeli jest to pierwotny posiadacz procesu, mówimy o wędrówce inicjowanej przez nadawcę (ang. sender-initiated). Gdy natomiast inicjatywę podejmuje maszyna docelowa, na której ma się wykonywać proces, mamy do czynienia z wędrówką inicjowaną przez odbiorcę (ang. receiver-initiated).
Migracja, a lokalnezasoby Wiązanie zasobów do maszyn Akcje podejmowanew stosunkudoreferencjido lokalnychzasobówprzy migracji kodu na inną maszynę. GR – ustanowić globalną referencję w skali systemu, MV – przenieść zasób, CP – kopiować wartość zasobu, RB – ponownie powiązać proces do lokalnie dostępnych zasobów. Wiązanie procesu do zasobu
Migracja, a lokalnezasoby Wraz z wędrówką procesu często występuje konieczność zmiany odniesienia do zasobów. Rodzaj wiązania pozostaje zawsze ten sam. To w jaki sposób zostanie zmienione odniesienie do danego zasobu, zależy od sposobu jego powiązania z konkretną maszyną. Zasoby niepołączone (ang. unattachedresources) można w stosunkowo łatwy sposób przenosić między maszynami np. pliki z danymi. Bardziej kłopotliwymi zasobami są zasoby umocowane (ang. astenedresources). Ich przeniesienie jest możliwe, aczkolwiek koszt jest nieraz na tyle wysoki, że praktycznie jest to nieopłacalne. W końcu mamy zasoby nieruchome (ang. fixedresources), których przeniesienie jest niemożliwe. Są to m.in. urządzenia do wykonywania pewnego typu zadań np. drukarka, ploter. Podczas wędrówki procesu możemy postąpić z jego zasobami w różny sposób, w zależności od rodzaju zasobu. Jeżeli zasób jest niepołączony, to zazwyczaj jest on przenoszony lub kopiowany, jeżeli nie jest to wiązanie przez identyfikator. Zasoby związane przez typ można związać z reguły na nowo z zasobem dostępnym lokalnie, jeżeli taki jest oczywiście dostępny. W przypadku zasobów nieruchomych często jedyną możliwością są globalne odniesienia. Zasoby wiązane przez wartość dają również możliwość skopiowania samej wartości, chyba że mamy do czynienia z zasobami nieruchomymi.
Migracja w systemach heterogenicznych (2) Zasadazachowaniastosumigracjido wspierania migracji segmentuwykonaniaw środowisku heterogenicznym. Migracja kodu ograniczona do specyficznych punktów wykonania. Stos migracji (migrationstack) – kopia stosu programu niezależna od platformy sprzętowej. W przypadku systemów rozproszonych istotnym czynnikiem przy ich projektowaniu jest heterogeniczność. Szczególnie widać to właśnie w przypadku procesów i ich wędrówki. Dopóki rozpatrujemy identyczne maszyny, czyli mamy do czynienia ze środowiskiem homogenicznym, dopóty nie istnieje wiele problemów związanych z różnicami wewnątrz środowiska maszyn i oprogramowania.
Migracja w systemach heterogenicznych (3) Możliwość wykonania identycznego kodu na różnych typach maszyn i właściwego przechowywania stanu procesu są kluczowe dla poprawnego wykonania operacji przeniesienia procesu. Stopień komplikacji wędrówki procesu w systemie zależy oczywiście od typu wędrówki. Jeżeli jest to przenośność słaba, problem sprowadza się do wygenerowania kodu dla odpowiednich typów platform. Nie ma tu natomiast przeniesienia segmentu wykonania, który może znacząco się różnić w zależności od architektury maszyny. Przykładowym rozwiązaniem, które zastosowano m.in. dla języka Java jest zezwolenie na wędrówkę procesu tylko w określonych punktach jego wykonywania np. przy wywoływaniu metody, wtedy też aktualizowany jest tzw. stos wędrówki (ang. migrationstack). Stos wędrówki jest niczym innym jak kopią stosu programu ale przechowywaną w sposób niezależny od maszyny. Za każdym razem kiedy proces wchodzi do podprogramu i z niego wychodzi odpowiednie dane ze stosu, identyfikator wywołanego podprogramu oraz etykieta powrotu (adres od którego należy kontynuować przetwarzanie po powrocie z podprogramu) są przetaczane (ang. marshaled) i odkładane na stosie wędrówki. Stos wędrówki jest w razie wędrówki procesu przenoszony na maszynę docelową i tam odwrotnie przetaczany (ang. unmarshaled), tak aby można było odtworzyć stos fazy wykonywania.
Architektura systemu D’Agents Role silnika, spełniającego funkcje systemu agentowego, przejął program D’Agents powstały w USA. System ten realizuje kilka podstawowych celów, które zapewniają sprawne i wydajne działanie. Pierwszym jest obsługa kilku języków w których może być napisany program agenta (Tcl, Java, Scheme). Drugim jest redukcja poleceń związanych z migracją do pojedynczej komendy która mogła zachować aktualny stan agenta, oraz przesłać go do innego serwera. Dzięki temu podczas pisania kodu agenta nie trzeba zajmować się detalami transmisji, nawet jeżeli zdalny komputer jest przenośny i może być przez nieokreślony czas niedostępny w sieci. Trzecim celem jest elastyczny, wydajny, niskopoziomowy mechanizm komunikacji, który ukrywa detale komunikacji i zaimplementowany jest na poziomie kolejkowania wiadomości lub strumieni danych. Mechanizmy wyższego poziomu nie są zawarte w podstawowym systemie, lecz na poziomie programu agenta. Dzięki przedstawionym na rysunku rozłożeniu systemu na warstwy, program agenta może wykorzystywać mechanizm, który jest najbardziej dostosowany do aktualnie wykonywanego zadania.
Architektura systemu D’Agents - opis Kolejne założenia systemu implikują użycie języka wysokiego poziomu, jako głównego do tworzenia programu agentów, oraz wykorzystanie protokołu TCP/IP, jako głównego mechanizmu transportu. Oprócz tego system zawiera odpowiednie zabezpieczenie pod względem ochrony danych, a co za tym idzie ochrona każdego serwera fizycznego przed wrogimi programami. Wielowarstwowa architektura systemu D’Agents. Pięć poziomów składa się na API dostępnych mechanizmów transportu: serwer akceptujący nadchodzące wiadomości i będący mediatorem pomiędzy agentami, niezależne od języka jadro, interpreter dla każdego języka i właściwa obsługa agenta. Ochrona systemu możliwa jest z pośrednictwem cyfrowych sygnatur agentów, które dzięki temu mogą być identyfikowane jako przyjazne. Oprócz tego istnieje odpowiedni mechanizm tolerancji błędów, które są nieuniknione w niepewnym medium jakim jest Internet.
Przeglądmigracji kodu wD'Agents (1) proc factorial n { if ($n 1) { return 1; } # fac(1) = 1expr $n * [ factorial [expr $n – 1] ] # fac(n) = n * fac(n – 1) } set number … # tells which factorial to compute set machine … # identify the target machine agent_submit $machine –procs factorial –vars number –script {factorial $number } agent_receive … # receive the results (left unspecified for simplicity) Prosty przykład agenta Tel wD'Agentswysyłającegoskryptdo zdalnej maszyny (źródło [gray.r95])