Sop_07_lab.pdf
(
240 KB
)
Pobierz
529566712 UNPDF
Laboratorium systemów operacyjnych – ćwiczenie nr 7.
[ilość modułów: 1]
Temat zajęć: Obsługa procesów w systemie.
Procesy macierzyste i potomne, tworzenie procesów potomnych,
uruchamianie programów, przekierowywanie strumieni
standardowych, implementacja przykładowych programów obsługi
procesów
I. Obsługa procesów.
Proces (zwany też zadaniem) jest jednostką aktywną, kontrolowaną przez system operacyjny i
związaną z wykonywanym programem. Proces ma przydzielone zasoby typu pamięć (segment kodu,
segment danych, segment stosu, segment danych systemowych), procesor, urządzenia zewnętrzne
itp. Część przydzielonych zasobów jest do wyłącznej dyspozycji procesu (np. segment danych,
segment stosu), część jest współdzielona z innymi procesami (np. procesor, segment kodu w
przypadku współbieżnego wykonywania tego samego programu w ramach kilku procesów).
W zależności od aktualnie posiadanych zasobów wyróżnia się stany procesu (np. wykonywany,
uśpiony, gotowy), które zmieniają się cyklicznie w związku z wykonywanym programem lub ze
zdarzeniami zachodzącymi w systemie. Szczegółowy stan procesu, umożliwiający kontynuację jego
wykonywania po przerwaniu nazywany jest kontekstem procesu.
W zakresie obsługi procesów system UNIX udostępnia mechanizm tworzenia nowych
procesów, usuwania procesów oraz uruchamiania programów. Każdy proces, z wyjątkiem procesu
systemowego o identyfikatorze 1, tworzony jest przez inny proces, który staje się jego przodkiem
zwanym też procesem rodzicielskim lub krótko rodzicem. Nowo utworzony proces nazywany jest
potomkiem lub procesem potomnym. Procesy w systemie UNIX tworzą zatem drzewiastą strukturę
hierarchiczną, podobnie jak katalogi.
Potomek tworzony jest w wyniku wywołania przez przodka funkcji systemowej
fork
. Po
utworzeniu potomek kontynuuje wykonywanie programu swojego przodka od miejsca wywołania
funkcji
fork
. Proces może się zakończyć dwojako: w sposób naturalny przez wywołanie funkcji
systemowej
exit
lub w wyniku reakcji na sygnał. Funkcja systemowa
exit
wywoływana jest
niejawnie na końcu wykonywania programu przez proces lub może być wywołana jawnie w każdym
innym miejscu programu. Zakończenie procesu w wyniku otrzymania sygnału nazywane jest
zabiciem. Proces może otrzymać sygnał wysłany przez jakiś inny proces (również przez samego
siebie) za pomocą funkcji systemowej
kill
lub wysłany przez jądro systemu operacyjnego.
Proces macierzysty może się dowiedzieć o sposobie zakończenia bezpośredniego potomka przez
wywołanie funkcji systemowej
wait
. Jeśli wywołanie funkcji
wait
nastąpi przed zakończeniem
potomka, przodek zostaje zawieszony w oczekiwaniu na to zakończenie.
Jeżeli proces macierzysty zakończy działanie przed procesem potomnym, to proces potomny
nazywany jest
sierotą
(ang.
orphan
) i jest „adoptowany” przez proces systemowy
init
, który staję się
w ten sposób jego przodkiem. Jeżeli proces potomny zakończył działanie przed wywołaniem funkcji
wait
w procesie macierzystym, potomek pozostanie w stanie
zombi
(proces taki nazywany jest
zombi, upiorem, duchem lub mumią). Zombi jest procesem, który zwalnia wszystkie zasoby (nie
zajmuje pamięci, nie jest mu przydzielany procesor), zajmuje jedynie miejsce w tablicy procesów w
jądrze systemu operacyjnego i zwalnia je dopiero w momencie wywołania funkcji
wait
przez proces
macierzysty, lub w momencie zakończenia procesu macierzystego.
W ramach istniejącego procesu może nastąpić uruchomienie innego programu w wyniku
wywołania jednej z funkcji systemowych
execl
,
execlp
,
execle
,
execv
,
execvp
,
execve
. Funkcje te
będą określane ogólną nazwą
exec
. Uruchomienie nowego programu oznacza w rzeczywistości
zmianę programu wykonywanego dotychczas przez proces, czyli zastąpienie wykonywanego
programu innym programem, wskazanym odpowiednio w parametrach aktualnych funkcji
exec
.
Bezbłędne wykonanie funkcji
exec
oznacza zatem bezpowrotne zaprzestanie wykonywania
str. nr
1
/10
Czas realizacji zajęć:
90 min.
Zakres materiału, jaki zostanie
zrealizowany podczas zajęć:
Laboratorium systemów operacyjnych – ćwiczenie nr 7.
[ilość modułów: 1]
bieżącego programu i rozpoczęcie wykonywania programu, którego nazwa jest przekazana jako
argument. W konsekwencji, z funkcji systemowej
exec
nie ma powrotu do programu, gdzie nastąpiło
jej wywołanie, o ile wykonanie tej funkcji nie zakończy się błędem.
Wyjście z funkcji
exec
można więc traktować jako jej błąd bez sprawdzania zwróconej wartości.
Funkcje służące do obsługi procesów opisane są w 2 i 3części pomocy systemowej i w większości
zdefiniowane w plikach
sys/types.h
oraz
unistd.h.
II. Funkcje systemowe i ich argumenty.
●
int fork( void );
Wartości zwracane:
poprawne wykonanie funkcji: utworzenie procesu potomnego; W procesie macierzystym funkcja
zwraca identyfikator (pid) procesu potomnego (wartość większą od 1), a w procesie potomnym
wartość 0.
zakończenie błędne: -1
Możliwe kody błędów (
errno
) w przypadku błędnego zakończenie funkcji:
EAGAIN – błąd alokacji wystarczającej ilości pamięci na skopiowanie stron rodzica i zaalokowanie
struktury zadań
ENOMEM – nie można zaalokować niezbędnych struktur jądra z powodu braku pamięci
UWAGI:
W momencie wywołania funkcji (przez proces który właśnie staje się przodkiem) tworzony jest
proces potomny, który wykonuje współbieżnie ze swoim przodkiem ten sam program. Potomek
rozpoczyna wykonywanie programu od wyjścia z funkcji
fork
i kontynuuje wykonując kolejną
instrukcję, znajdującą się w programie po wywołaniu funkcji
fork
. Do funkcji
fork
wchodzi zatem
tylko proces macierzysty, a wychodzą z niej dwa procesy: macierzysty i potomny, przy czym każdy z
nich otrzymuję inną wartość zwrotną funkcji
fork
. Wartością zwrotną funkcji
fork
w procesie
macierzystym jest identyfikator (PID) potomka, a w procesie potomnym wartość 0. W przypadku
błędnego wykonania funkcji
fork
potomek nie zostanie utworzony, a proces wywołujący otrzyma
wartość -1.
●
int getpid(void) oraz int getppid(void)
Wartości zwracane:
poprawne wykonanie funkcji: zwrócenie własnego identyfikatora (w przypadku funkcji
getpid
) lub
identyfikator procesu macierzystego (dla funkcji
getppid
).
zakończenie błędne: -1
●
void exit(int status)
Wartości zwracane:
poprawne wykonanie funkcji: przekazanie w odpowiednie miejsce tablicy procesów wartości
status
,
która może zostać odebrana i zinterpretowana przez proces macierzysty.
zakończenie błędne: -1
UWAGI:
Funkcja kończy działanie procesu, który ją wykonał i powoduje przekazanie w odpowiednie miejsce
tablicy procesów wartości
status
, która może zostać odebrana i zinterpretowana przez proces
macierzysty.
str. nr
2
/10
Laboratorium systemów operacyjnych – ćwiczenie nr 7.
[ilość modułów: 1]
Jeśli proces macierzysty został zakończony, a istnieją procesy potomne – to wykonanie ich nie jest
zakłócone, ale ich identyfikator procesu macierzystego wszystkich procesów potomnych otrzyma
wartość 1 będącą identyfikatorem procesu
init
(proces potomny staje się sierotą (ang.
orphan
) i jest
„adoptowany” przez proces systemowy init). Funkcja
exit
zdefiniowana jest w pliku
stdlib.h.
exit(0)
– oznacza poprawne zakończenie wykonanie procesu
exit(dowolna wartość różna od 0 ) – oznacza wystąpienie błędu
●
int wait(int *status) oraz int waitpid( int pid, int *status, int
options)
Wartości zwracane:
poprawne wykonanie funkcji: identyfikator procesu potomnego, który się zakończył
zakończenie błędne: -1 lub 0 jeśli użyto opcji WNOHANG, a nie było dostępnego żadnego potomka
Możliwe kody błędów (
errno
) w przypadku błędnego zakończenie funkcji:
ECHILD – jeśli proces o zadanym identyfikatorze
pid
nie istnieje lub nie jest potomkiem
procesu wywołującego. (Może się to zdarzyć również w przypadku potomka, który ustawił akcję
obsługi sygnału SIGCHLD na SIG_IGN)
EINVAL – jeśli argument
options
jest niepoprawny.
EINTR – jeśli opcja WNOHANG nie była ustawiona, a został przechwycony niezablokowany
sygnał lub SIGCHLD.
Argumenty funkcji:
status
– status zakończenia procesu (w przypadku zakończenia w sposób normalny) lub numer
sygnału w przypadku zabicia potomka lub wartość NULL, w przypadku gdy informacja o stanie
zakończenia procesu nie jest istotna
pid
– identyfikator potomka, na którego zakończenie czeka proces macierzysty
•
pid
< -1 oznacza oczekiwanie na dowolny proces potomny, którego identyfikator grupy
procesów jest równy modułowi wartości
pid
.
•
pid
= -1 oznacza oczekiwanie na dowolny proces potomny; jest to takie samo zachowanie,
jakie stosuje funkcja
wait
.
•
pid
= 0 oznacza oczekiwanie na każdy proces potomny, którego identyfikator grupy procesu
jest równe identyfikatorowi wołającego procesu.
•
pid
> 0 oznacza oczekiwanie na potomka, którego identyfikator procesu jest równy wartości
pid
.
options
– jest sumą OR zera lub następujących stałych:
•
WNOHANG oznacza natychmiastowe zakończenie jeśli potomek się nie zakończył.
•
WUNTRACED oznacza zakończenie także dla procesów potomnych, które się zatrzymały, a
których
status
jeszcze nie został zgłoszony.
UWAGI:
Oczekiwanie na zakończenie procesu potomnego. Funkcja zwraca identyfikator (
pid
) procesu, który
się zakończył. Pod adresem wskazywanym przez zmienną
status
umieszczany jest status
zakończenia, który zawiera albo numer sygnału (najmniej znaczące 7 bitów), albo właściwy status
zakończenia (bardziej znaczący bajt).
Gdy działa parę procesów potomnych zakończenie jednego z nich powoduje powrót z funkcji wait.
Jeżeli funkcja
wait
zostanie wywołana w procesie macierzystym przed zakończeniem procesu
potomnego, wykonywanie procesu macierzystego zostanie zawieszone do momentu zakończenia
potomka. Jeżeli proces potomny zakończył działanie przed wywołaniem funkcji
wait
, powrót z
funkcji
wait
nastąpi natychmiast, a w czasie pomiędzy zakończeniem potomka, a wywołaniem
str. nr
3
/10
Laboratorium systemów operacyjnych – ćwiczenie nr 7.
[ilość modułów: 1]
funkcji
wait
przez jego przodka potomek pozostanie w stanie
zombi.
Zombi nie jest tworzony, gdy
proces macierzysty ignoruje sygnał SIGCLD .
Funkcja
exit
zdefiniowana jest w pliku
sys/types.h
oraz
sys/wait.h
.
●
rodzina funkcji exec
int execl ( char *path, char *arg0, ..., char *argn, char *null )
int execlp( char *file, char *arg0, ..., char *argn, char *null )
int execv ( char *path, char * argv[] )
int execvp( char *file, char * argv[] )
int execle( char * path, char *arg0, ..., char *argn,char
*null,char *envp[] )
int execve( char * path, char *argv[],char *envp[] )
Wartości zwracane:
poprawne wykonanie funkcji: wywołanie programu podanego jako parametr
zakończenie błędne: -1
Możliwe kody błędów (
errno
) w przypadku błędnego zakończenie funkcji: Każda z tych funkcji
może zakończyć się niepowodzeniem i ustawić jako wartość
errno
dowolny błąd określony dla
funkcji bibliotecznej
execve
(2).
Argumenty funkcji:
path, file
– pełna nazwa ścieżkowa lub nazwa pliku z programem
arg0
...
argn
– nazwa i argumenty programu który ma być wywołany
UWAGI:
W ramach istniejącego procesu może nastąpić uruchomienie innego programu w wyniku wywołania
jednej z funkcji systemowych
execl
,
execlp
,
execle
,
execv
,
execvp
,
execve
. Funkcje te określane są
ogólną nazwą
exec
. Bezbłędne wykonanie funkcji
exec
oznacza bezpowrotne zaprzestanie
wykonywania bieżącego programu i rozpoczęcie wykonywania programu, którego nazwa jest
przekazana przez argument.
W wyniku wywołania funkcji typu
exec
następuje reinicjalizacja segmentów kodu, danych i stosu.
Nie zmieniają się atrybuty procesu takie jak pid, ppid, tablica otwartych plików i kilka innych
atrybutów z segmentu danych systemowych
Różnice pomiędzy wywołaniami funkcji
exec
wynikają głównie z różnego sposobu budowy ich listy
argumentów: w przypadku funkcji
execl
i
execlp
są one podane w postaci listy, a w przypadku
funkcji
execv
i
execvp
jako tablica. Zarówno lista argumentów, jak i tablica wskaźników musi być
zakończona wartością NULL. Funkcja
execle
dodatkowo ustala środowisko wykonywanego procesu.
Funkcje
execlp
oraz
execvp
szukają pliku wykonywalnego na podstawie ścieżki przeszukiwania
podanej w zmiennej środowiskowej PATH. Jeśli zmienna ta nie istnieje, przyjmowana jest domyślna
ścieżka :/bin:/usr/bin.
Wartością zwrotną funkcji typu
exec
jest
status
, przy czym jest ona zwracana tylko wtedy, gdy
funkcja zakończy się niepoprawnie, będzie to zatem wartość –1.
Funkcje
exec
nie tworzą nowego procesu, tak jak w przypadku funkcji fork!!!
str. nr
4
/10
Laboratorium systemów operacyjnych – ćwiczenie nr 7.
[ilość modułów: 1]
PRZYKŁADY
execl(„/bin/ls”, „ls”, „-l”,null)
execlp(„ls”, „ls”, „-l”,null)
char* const av[]={„ls”, „-l”, null}
execv(„/bin/ls”, av)
char* const av[]={„ls”, „-l”, null}
execvp(„ls”, av)
III. Przykłady użycia funkcji obsługi procesów.
Listingi
1
i
2
przedstawiają program, który ma zasygnalizować początek i koniec swojego
działania przez wyprowadzenia odpowiedniego tekstu na standardowe wyjście.
#include <stdio.h>
2
main(){
4 printf("Poczatek\n");
fork
();
6 printf("Koniec\n");
}
Listing 1: Przykład działania funkcji
fork
Opis programu
: Program jest początkowo wykonywany przez jeden proces. W wyniku wywołania
funkcji systemowej
fork
(linia 5) następuje rozwidlenie i tworzony jest proces potomny, który
kontynuuje wykonywanie programu swojego przodka od miejsca utworzenia. Wynik działania
programu jest zatem następujący:
Poczatek
Koniec
Koniec
#include <stdio.h>
2
main(){
4 printf("Poczatek\n");
execlp
("ls", "ls", "-a", NULL);
6 printf("Koniec\n");
}
Listing 2: Przykład działania funkcji
exec
Opis programu:
W wyniku wywołania funkcji systemowej
execlp
(linia 5) następuje zmiana
wykonywanego programu, zanim sterowanie dojdzie do instrukcji wyprowadzenia napisu
Koniec
na standardowe wyjście (linia 6). Zmiana wykonywanego programu powoduje, że sterowanie nie
wraca już do poprzedniego programu i napis
Koniec
nie pojawia się na standardowym wyjściu w
ogóle.
Listing
3
przedstawia program, który zaznacza początek i koniec swojego działania zgodnie z
oczekiwaniami, tzn. napis
Poczatek
pojawia się przed wynikiem wykonania programu (polecenia)
ls
, a napis
Koniec
pojawia się po zakończeniu wykonywania
ls
.
str. nr
5
/10
Plik z chomika:
deli35
Inne pliki z tego folderu:
naumowicz_systemy_operacyjne.pdf
(5091 KB)
Sop_16_wyk_1.1.pdf
(3196 KB)
Sop_15_wyk_1.1.pdf
(3033 KB)
Sop_13_wyk_1.0.pdf
(4064 KB)
Sop_11_wyk_1.0.pdf
(2894 KB)
Inne foldery tego chomika:
1-wszy filmik,dokładna jego analiza itp
3.TERTIUS
A S T R O L O G I A - dla tych którzy doceniają cudny wrzechświat nas otaczający !!!
Al Pacino
Analiza finansowa i strategiczna
Zgłoś jeśli
naruszono regulamin