Model procesu w systemie Linux. Tomasz Borzyszkowski



Podobne dokumenty
Poniższe funkcje opisane są w 2 i 3 części pomocy systemowej.

Procesy. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 9 października 2011

Temat zajęć: Obsługa procesów w systemie.

Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)

SYSTEMY OPERACYJNE I laboratorium 3 (Informatyka stacjonarne 2 rok, semestr zimowy)

2. Zarządzanie procesami

Procesy. S. Samolej: Procesy

Systemy Operacyjne 1 Laboratorium 2 Procesy i sygnały w Linuksie (jeden tydzień) dr inż. Arkadiusz Chrobot

Procesy w systemach UNIX i Linux

Wykład 3. Procesy i wątki. Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB

Systemy Operacyjne I: Procesy

1.1 Definicja procesu

Obsługa plików Procesy

4. Procesy pojęcia podstawowe

4. Procesy pojęcia podstawowe

Projektowanie oprogramowania systemów PROCESY I ZARZĄDZANIE PROCESAMI

procesy odrębne dzielone

Komunikacja za pomocą potoków. Tomasz Borzyszkowski

Systemy operacyjne III

Procesy i wątki. Blok kontrolny procesu. Proces. Proces - elementy. Stan procesu

Proces y i y w i ąt ą ki

Programowanie Współbieżne. W Linuxie/Unixie

Działanie systemu operacyjnego

2. Zarządzanie procesami

Pliki. Funkcje tworzące pliki i operujące na nich opisane są w części 2 pomocy systemowej. Tworzenie i otwieranie plików:

2. Zarządzanie procesami

pami eć operacyjna przechowuje dane do przetworzenia, tymczasowe dane pomocnicze,

Procesy, wątki i zasoby

4. Procesy pojęcia podstawowe

Zarządzanie procesami (omawiane zagadnienia)

Uruchamianie programów w systemie Linux, potoki, strumienie, procesy, alias

Zarządzanie procesami i wątkami

Linux: Procesy. Systemy Operacyjne. Mateusz Hołenko. 26 marca 2013

projektowanie systemu

Futex (Fast Userspace Mutex) Łukasz Białek

Procesy, zasoby i wątki

Procesy, zasoby i wątki

Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi.

Autor: dr inż. Zofia Kruczkiewicz, Programowanie aplikacji internetowych 1

Jądro Powłoka System plików Programy użytkowe

Procesy, zasoby i wątki

SYSTEMY OPERACYJNE WYKLAD 6 - procesy

przypadków wywo lanie systemowe (funkcja systemowa) lub funkcja biblioteczna zwraca wartość 1(czasamiNULL) iprzypisujezmiennej zewn etrznej,

Procesy pojęcia podstawowe. 1.1 Jak kod źródłowy przekształca się w proces

Systemy Operacyjne Ćwiczenia

Systemy Operacyjne - Operacje na plikach

4.2 Sposób korzystania z l acza

Obsługa sygnałów. Tomasz Borzyszkowski

Procesy i wątki. Blok kontrolny procesu. Proces. Proces - elementy. Stan procesu. Blok kontrolny procesu

Sygnały. 7. Sygnały (2005/2006)

Systemy operacyjne. Systemy operacyjne. Systemy operacyjne. Program wykładów. Strona WWW przedmiotu: Program ćwiczeń projektowych

Stan procesu. gotowy - czeka na przydział procesora, zakończony - zakończył działanie.

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

SYSTEMY OPERACYJNE: STRUKTURY I FUNKCJE (opracowano na podstawie skryptu PP: Królikowski Z., Sajkowski M. 1992: Użytkowanie systemu operacyjnego UNIX)

Instrukcja do laboratorium Systemów Operacyjnych (semestr drugi)

Laboratorium systemów operacyjnych ćwiczenie nr 3. [ilość modułów: 1] Temat zajęć: Procesy w systemie operacyjnym

Architektura systemu komputerowego. Działanie systemu komputerowego. Przerwania. Obsługa przerwań (Interrupt Handling)

System operacyjny MACH

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)

1. Procesy i współbieżność

Zarządzanie Procesami

Argumenty wywołania programu, operacje na plikach

Moduł 4: Strumienie, potoki, sterowanie procesami

Prezentacja systemu RTLinux

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Działanie systemu operacyjnego

Pamięć współdzielona

Jak wiemy, wszystkich danych nie zmieścimy w pamięci. A nawet jeśli zmieścimy, to pozostaną tam tylko do najbliższego wyłączenia zasilania.

Programowanie współbieżne Wykład 2. Iwona Kochańska

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

IPC: Kolejki komunikatów

Działanie systemu operacyjnego

Wstęp do Programowania, laboratorium 02

Mikroprocesor Operacje wejścia / wyjścia

Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011

Wątek - definicja. Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego

Łącza nienazwane(potoki)

Kolejki FIFO (łącza nazwane)

Procesy. 5. Procesy (2005/2006)

Tablice (jedno i wielowymiarowe), łańcuchy znaków

System plików warstwa logiczna

1 Wątki 1. 2 Tworzenie wątków 1. 3 Synchronizacja 3. 4 Dodatki 3. 5 Algorytmy sortowania 4

Działanie systemu operacyjnego

2.1 Pojęcie wątku Modele wielowątkowości Wybrane zagadnienia wielowątkowości Wątki POSIX... 18

Systemy Operacyjne 1 Laboratorium 3 Potoki i łącza nazwane w Linuksie (jeden tydzień) dr inż. Arkadiusz Chrobot

UXP1A Unix Programowanie i Architektura

Procesy, pliki, potoki, sygnały - uzupełnienie

Systemy operacyjne na platformach mobilnych 2 Podstawy obsługi powłoki Bash

Zmienne, stałe i operatory

Instytut Teleinformatyki

Mikroinformatyka. Wielozadaniowość

w odróżnieniu od procesów współdzielą przestrzeń adresową mogą komunikować się za pomocą zmiennych globalnych

Systemy Operacyjne 2: Wątki pthreads. dr inż. Arkadiusz Chrobot

Krótki kurs programowania współbieżnego

Stworzenie klasy nie jest równoznaczne z wykorzystaniem wielowątkowości. Uzyskuje się ją dopiero poprzez inicjalizację wątku.

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

Budowa systemów komputerowych

Programowanie równoległe i rozproszone. Monitory i zmienne warunku. Krzysztof Banaś Programowanie równoległe i rozproszone 1

Transkrypt:

Model procesu w systemie Linux Tomasz Borzyszkowski

Definicja procesu klasyka Definicja [M.Bach WNT95] Proces jest wykonaniem programu i składa się ze zbiorowości bajtów, które CPU interpretuje jako instrukcje maszynowe (tzw. tekst), dane i stos. Jądro steruje wykonaniem procesów (stwarzając wrażenie, że wiele procesów wykonuje się jednocześnie); kilka procesów może być wcieleniem jednego programu. Proces wykonuje się przechodąc przez ściśle ustalony ciąg instrukcji (stanowiący całość) i nigdy nie wykonuje skoków do instrukcji innego procesu tzn. czyta i zapisuje swoje dane oraz stos, lecz nie może czytać ani zapisywać danych i stosu innych procesów. Procesy komunikują się z innymi procesami i z resztą świata za pomocą funkcji systemowych. 2

Co proces wie? Dla każdego programu/procesu/wykonania jądro systemu utrzymuje informacje o: Bieżącym stanie wykonania (np. czekanie na powrót z trybu jądra,...), zwanym kontekstem programu Plikach, do których program ma dostęp Uprawnieniach dotyczących programu (przeważnie dziedziczone po właścicielu procesu lub grupie procesów) Bieżącym katalogu programu Obszerze pamięci, do którego program ma dostęp, i zawartości tego obszaru Procesy rozumiane jako wykonania kodu posiadające własności przedstawione powyżej były podstawową jednostką pracy pierwszych systemów Unixowych. Tylko procesy miały możliwość działania na procesorze. 3

Dodatkowa komplikacja wątki Wątek umożliwia pojedynczemu programowi działanie w kilku miejscach kodu jednocześnie. Wszystkie wątki utworzone przez program dzielą większość zasobów programu, tj: informacje o otwartych plikach, uprawnienia, bieżący katalog, obraz pamięci,.... Gdy tylko jeden z wątków procesu modyfikuje zmienną globalną, pozostałe natychmiast widzą jej nową wartość. Wiele implementacji systemów Unixowych, w tym wersje Systemu V (AT&T), zaprojektowano tak, aby podstawową jednostką systemu zarządzaną przez jądro był wątek, a procesy stały się kolekcjami wątków dzielących zasoby. Dzięki współdzieleniu zasobów przełączanie między wątkami jest znacznie szybsze niż między procesami. Z powyższych powodów w wielu systemach Unixowych istnieje podwójny model procesu, w którym odróżnia się wątki od procesów. 4

Model procesu Linux Przełączanie kontekstu procesów w Linuxie było zawsze bardzo szybkie, podobnie jak przełączanie wątków w innych Unixach. Zasugerowało to twórcom Linuxa, że nie należy zmieniać tego co dobrze działa by wprowadzić wątki. Zdecydowano się za to na by pozwolić procesom na korzystanie z zasobów dzielonych w bardziej liberalny sposób. W Linuxie proces jest zdefiniowany wyłącznie jako jednostka, której działaniem zarządza system, a jedyną rzeczą charakterystyczną procesu jest jego kontekst wykonania. Nie wynika z tego nic dla dzielenia zasobów, ponieważ proces macierzysty, tworzący proces potomny, ma pełną kontrolę nad tym, które zasoby będą między nimi dzielone. Takie podejście pozwala zachować tradycyjny Unixowy model zarządzania procesami. Interfejs wątków jest budowany poza jądrem. 5

Atrybuty procesów Identyfikator procesu (PID, Process ID): numer jednoznacznie identyfikujący proces Identyfikator rodzica procesu (PPID, Parent Process ID): identyfikator PID procesu będącego rodzicem danego procesu. Liczba nice: liczba wyznaczająca ważność danego procesu w stosunku do innych procesów. Nie jest to to samo co priorytet procesu wyliczany dynamicznie na podstawie liczby nice i zużycia zasobów CPU przez dany proces. TTY: urządzenie reprezentujące terminal kontrolny danego procesu. RUID i EUID (Real User ID i Effective User ID): RUID to ID użytkownika, który uruchomił dany proces. EUID zwykle równy RUID chyba, że użytkownik uruchomił program z ustawionym prawem SUID. RGID i EGID (Real Group ID i Effective Group ID): podobnie jak RUID i EUID. Zobacz: guiduid.c 6

Atrybuty procesów implementacja PID jest dodatnią liczbą całkowitą, która jednoznacznie określa działający proces i jest zapamiętywana w zmiennych typu pid_t. Jeżeli proces ginie, jego kod wyjścia jest pamiętany tak długo w tablicy procesów, aż poprosi o niego proces macierzysty. Procesy, które zakończyły działanie, a informacja o nich jest utrzymywana by mieć dostęp do ich kodu wyjścia, są nazywane zombie. Zaraz po odczytaniu kodu wyjścia procesu zombie jest on usuwany. Jeżeli proces rodzica kończy działanie, przed zakończeniem procesów potomnych, procesy potomne stają się potomkami procesu init. Proces init jest pierwszym procesem, który powstaje podczas inicjowania systemu. Jego PID ma wartość 1. Jednym z jego głównych zadań jest odbieranie wartości kodów wyjścia procesów, których rodzice zginęli, by móc usunąć je z tablicy jądra. Proces może poznać swój PID i PPID za pomocą funkcji getpid() i getppid(). Zobacz: getpid.c 7

Cykl życia procesu Tryb użytkownika Wywołanie funkcji systemowej lub przerwanie zasypianie Tryb jądra powrót wybranie do wykonania przerwanie powrót z przerwania Uśpiony budzenie Gotowy do wykonania 8

Argumenty programu Istnieją dwa typy wartości przekazywanych do nowych programów w chwili ich uruchomienia: Argumenty wiersza poleceń; prototyp funkcji main(): int main(int argc, char *argv[]); Wartości zwracane, interpretowane jest tylko 7 najmniej znaczących bitów: 0 = OK; od -1 do -128 = proces zatrzymany przez inny proces lub jądro; od 1 do 127 = zakończenie z powodu błędu Zmienne środowiskowe. Zmienna environ zdefiniowana w pliku <unistd.h> zawiera wskaźnik do środowiska. Najczęściej ze zmiennych środowiska korzysta się za pośrednictwem funkcji: getenv(), putenv() oraz (niezgodna z POSIX ale występuje w BSD i Linuxie) setenv(). Zobacz: env{1,2}.c 9

Tworzenie procesów potomnych W Linuxie są dostępne dwie funkcje systemowe do tworzenia nowych procesów: fork() i clone(). Funkcja clone() służy do tworzenia wątków. Funkcja fork() posiada następującą własność: powrót z jej wywołania następuje nie raz, ale dwa razy. Raz w procesie macierzystym i raz w procesie potomnym. Zgodnie z POSIX nie można zakładać, który powrót będzie pierwszy. Każdy z powrotów z fork() przekazuje inną wartość. W procesie macierzystym jest to PID nowo utworzonego procesu potomnego, natomiast w procesie potomnym 0. Powyższa różnica jest jedyną różnicą widoczną w procesach. Proces potomny i macierzysty mają: ten sam obraz pamięci, te same uprawnienia, te same otwarte pliki, te same procedury obsługi przerwań,.... Zobacz: potomek.c 10

Nowe procesy fork-and-exec init PID 1 fork init PID 424 exec getty PID 424 exec login PID 424 sh exec PID 424 fork sh PID 536 exec exit grep PID 536 11

Uruchamianie programów exec Jak pokazano na poprzednim slajdzie do zapoczątkowania nowego procesu używa się funkcji fork() i funkcji z rodziny funkcji exec (). Główna różnicą pomiędzy funkcjami rodziny exec() jest sposób przekazywania parametrów. Wszystkie funkcje tej rodziny ostateczenie wykonują rzeczywistą funkcję systemową execve(). execl execle execlp execv execve execvp 12

Uruchamianie programów cd Wszystkie warianty exec() wykonują to samo zadanie: przekształcają proces wywołujący przez załadowanie nowego programu do jego przestrzeni pamięci. Jeśli wywołanie exec() jest pomyślne, wywołujący program zostaje całkowicie przykryty przez nowy program, wykonywany od samego początku. Stary program jest wymazywany przez nowy. Tak więc, nie ma żadnego powrotu z pomyślnego wywołania funkcji exec(). Przykład: int execl(const char *path, const char *argv0,..., const char *argvn, (char *)0); Pierwszy parametr jest nazwą (pełną) pliku zawierającego program do wykonania. Drugi jest nazwą programu lub polecenia bez ścieżki, reszta (bez ostatniego), to paramerty wywołania. Ostani wskaźnik NULL oznaczający koniec listy parametrów. Zobacz: runls.c runls2.c myecho.c runmyecho.c runls3.c 13

fork(), pliki i dane Tworzony za pomocą fork() proces potomny jest kopią swojego rodzica. W szczególności wszystkie zmienne procesu potomnego zachowują wartość, którą otrzymały w procesie rodzicielskim. Ponieważ dane dostępne dla potomka są kopią danych rodzica, zmiany w jednym procesie nie będą wpływać na wartość zmiennych w drugim procesie. Pliki otwarte w procesie rodzicielskim są też otwarte w procesie potomnym. Potomek utrzymuje swoją własną kopię deskryptorów plików. Jednak po wywołaniu fork() wskaźnik odczytu/zapisu dla każdego pliku jest współdzielony między potomkiem a rodzicem. Jest to możliwe, ponieważ wskaźnik odczytu/zapisu jest utrzymywany przez system i po każdej operacji wej/wyj system aktualizuje deskryptory plików. Zadanie: Napisz program, pokazujący, że zmienne programu w procesie rodzicielskim i potomnym mają te same wartości początkowe, ale są niezależne. Zobacz: proc_file.c 14

Kończenie procesów exit Wielokrotnie już używaliśmy funkcji exit() w programach w C do kończenia procesu. Argument funkcji exit() nazywamy stanem zakończenia procesu. Jego młodsze 8 bitów jest dostępne dla procesu rodzicielskiego, jeżeli wykonywał funkcję wait(). Proces rodzicielski może w ten sposób badać czy proces potomny zakończył się sukcesem (watość 0), czy porażką (wartość nie 0). Funkcja exit() wykonuje także pewną liczbę innych działań, np. zamyka wszystkie otwarte deskryptory plików. Programista może z jej wywołaniem związać własne funkcje obsługi zakończenia i wykonać tzw. gruntowne działania czyszczące, np. czyszczenie buforów. Do wiązania takiego używa się funkcję: int atexit(void (*func)(void) ); atexit() rejestruje funkcję wskazywaną przez func. Wszystkie zarejestrowane funkcje podczas zakończenia będą wywołane w kolejności odwrotnej do ich rejestracji. Istnieje także funkcja systemowa _exit(), działająca jak exit() ale bez czyszczenia. Zobacz: zakoncz.c 15

Synchronizacja procesów Zobacz: status.c Funkcja wait() chwilowo zawiesza wykonanie procesu, podczas gdy proces potomny działa. Po zakończeniu procesu potomnego, czekający proces rodzicielski zostaje wznowiony. Jeśli działa więcej niż jeden proces potomny i gdy tylko jeden z nich się zakończy, wait() powraca. Wartość zwracana przez funkcję wait() to zwykle ID procesu zakończonego potomka. Jeśli wait() zwróci (pid_t) -1, może to oznaczać, że nie istnieje żaden proces potomny, wówczas errno będzie zawierać kod błędu ECHILD. Funkcja wait() pobiera jeden argument, który jest wskaźnikiem do liczby całkowitej. Jeśli wskaźnik jest równy NULL, to argument jest ignorowany. Jeśli wskaźnik był różny od NULL, to po powrocie będzie zawierał wskazanie na status zakończenia procesu potomnego, przekazywany przez exit(). Wartość ta jest zapamiętywana w 8 starszych bitach wskazywanego wyniku (makro WEXITSTATUS). 8 młodszych bitów musi być równe 0 (makro WIFEXITED). 16

Czekanie na konkretny proces Do oczekiwania na zakończenie procesu potomnego o konkretnym numerze PID służy funkcja: pid_t waitpid( pid_t pid, int *status, int options); Pierwszy argument określa ID procesu potomnego, na który proces rodzicielski chce czekać. Jeżeli jest on ustawiony na -1 (oznacza dowolny proces potomny), a trzeci argument na 0, to zachowuje się dokładnie jak wait(). Drugi argument po powrocie będzie zawierał stan procesu potomnego. Trzeci argument może przybierać różne wartości zdefiniowane w <sys/wait.h>. Często używaną wartością jest WNOHANG. Powoduje powrót z waitpid() bez blokowania, tj. bez czekania na zakończenie potomka. Zachowanie takie może służyć do monitorowania procesu potomnego. Przy ustawionej fladze WNOHANG, waitpid() oddaje 0 jeżeli proces potomny jeszcze się nie zakończył. Zobacz: status2.c 17

Wielkość pliku Istnieje w systemie ograniczenie wielkości pliku, który może być utworzony za pomocą funkcji systemowej write. Służy do tego funkcja: long ulimit(int cmd, [long limit]); Aby uzyskać bieżącą wartość ograniczenia wiekości pliku, należy wywołać funkcję z cmd równym UL_GETFSIZE. Wartość zwrócona będzie wyrażona w blokach pamięci. Aby ustawić nowe ograniczenie wielkości pliku, należy wywołać funkcję z cmd równym UL_SETFSIZE ustawiając nowe ograniczenie wyrażone w blokach pamięci w drugim parametrze. Tylko administrator systemu może zwiększać ograniczenie wielkości plików. Natomiast procesy o UID takim jak właściciel pliku mogą zmniejszać to ograniczenie. 18

Priorytety procesów System decyduje o porcji CPU przydzielanej procesowi m.in. na podstawie wartości całkowitej nice. Wartość ta ma zakres od 0 do zależnego od systemu maksimum. Im wyższa liczba, tym niższy priorytet procesu. Uspołeczniony proces powinien, jeżeli to możliwe zmniejszać swój priorytet, przydzielając więcej czasu innym procesom, używając funkcji systemosej nice(). Pobiera ona jeden argument, liczbę dodawaną do aktualnej wartości nice. Administrator systemu jest jedynym użytkownikiem, który może dodawać do nice procesu wartości ujemne, zwiększając priorytet procesu. Zadanie: Sprawdzić działanie funkcji nice() oraz ulimit(). 19