Instrukcja do laboratorium Systemów Operacyjnych
(semestr drugi)
wiczenie drugie
Ć
Temat: Procesy i sygna y w Linuksie.
ł
Opracowanie:
mgr in . Arkadiusz Chrobot
ż
Wprowadzenie
1. Budowa procesu w Uniksie.
W systemach uniksowych (w tym w Linuksie) przestrzeń procesu u ytkownika
ż
mo na
ż
podzielić na dwa konteksty: kontekst u ytkownika
ż
i kontekst j dra.
ą
Pierwszy z nich mo e
ż być podzielony na sześć obszarów: tekstu, sta ych,
ł
zmiennych
zainicjowanych, zmiennych niezainicjowanych, sterty i stosu. Drugi zawiera
wy cznie
łą
dane. Obszar tekstu zawiera rozkazy maszynowe, które są wykonywane
przez sprz t.
ę
Ten obszar jest tylko do odczytu, a wi c
ę mo e
ż
go wspó dzieli
ł
ć kilka
procesów równocze nie.
ś
Obszar sta ych
ł
jest również tylko do odczytu. We
wspó czesnych
ł
systemach uniksowych jest
czony
łą
w jeden obszar z obszarem
tekstu. Obszar zmiennych zainicjowanych zawiera zmienne, którym zosta y
ł
przypisane warto ci
ś
pocz tkowe,
ą
ale proces mo e
ż je dowolnie modyfikowa .
ć Obszar
zmiennych
niezainicjowanych
(bss)
zawiera
zmienne,
które
mają
wartość
pocz tkow
ą
ą zero, a wi c
ę nie trzeba ich warto ci
ś
inicjuj cych
ą
przechowywać w pliku
programu. Sterta (ang. heap) i stos (ang. stack) tworzą w zasadzie jeden obszar –
sterta s u y
ł ż
do dynamicznego przydzielania dodatkowego obszaru w pami ci,
ę
natomiast na stosie przechowywane są ramki stosu, czyli informacje zwi zane
ą
z wywo aniem
ł
podprogramów. Sterta rozszerza się w stronę wy szych
ż
adresów,
natomiast
stos
w
stronę
ni szych
ż
adresów.
Proces
u ytkownika
ż
nie
ma
bezpo redniego
ś
dost pu
ę
do kontekstu j dra,
ą
który zawiera informacje o stanie tego
procesu. Ten obszar mo e
ż
być modyfikowany tylko przez j dro.
ą
Pewne warto ci
ś
w tym kontek cie
ś
mogą być modyfikowane z poziomu procesu u ytkownika
ż
poprzez
odpowiednie wywo ania systemowe.
ł
2. Tworzenie nowych procesów
Dzia aj cy
ł ą
proces mo e
ż stworzyć proces potomny u ywaj c
ż
ą wywo ania
ł
systemowego
fork(). W systemie Linux wywo anie
ł
to jest „opakowaniem” na wywo anie
ł
clone(),
które nie jest wywo aniem
ł
standardowym i nie nale y
ż
go bezpo rednio
ś
stosować
w programach, które mają być przeno ne.
ś
W Linuksie zastosowany jest wariant
tworzenia procesów okre lany
ś
po angielsku copy-on-write. Oznacza to, ze po
stworzeniu nowego procesu wspó dzieli
ł
on zarówno obszar tekstu, jak i obszar
danych (tj. stert ,
ę
stos, zmienne zainicjowane i niezainicjowane) z rodzicem.
Dopiero, kiedy któryś z nich b dzie
ę
próbował dokonać modyfikacji danych nast pi
ą
rozdzielenie obszaru danych (proces potomny otrzyma kopię obszaru rodziciela).
2
Aby wykonać nowy program nale y
ż w procesie potomnym u y
ż ć jednej z funkcji exec
(). Sterowanie z procesu rodzicielskiego do procesu potomnego nigdy bezpo rednio
ś
nie wraca, ale proces rodzicielski mo e
ż poznać status wykonania procesu potomnego
wykonuj c
ą jedną z funkcji wait(). Je li
ś
proces rodzicielski nie wykona tej funkcji to
proces potomny zostaje procesem zombie. W przypadku, gdy proces rodziciel
zako czy
ń
się wcze niej
ś
niż proces potomny, to ten ostatni jest „adoptowany” przez
proces init, którego PID (identyfikator procesu) wynosi „1” lub inne procesy nale
ce
żą
do tej samej grupy co proces macierzysty.
3. Sygna y
ł
Sygna y
ł
mo na
ż
uznać za prostą formę komunikacji mi dzy
ę
procesami, ale przede
wszystkim s u
ł żą one do powiadomienia procesu, e
ż zasz o
ł jakieś zdarzenie, st d
ą też
nazywa się je przerwaniami programowymi. Sygna y
ł
są asynchroniczne wzgl dem
ę
wykonania procesu (nie mo na
ż
przewidzieć kiedy się pojawi ).
ą
Mogą być wys ane
ł
z procesu do procesu lub z j dra
ą
do procesu. Programista ma do dyspozycji funkcję
kill(), która umo liwia
ż
wys anie
ł
sygna u
ł
do procesu o podanym PID. Z ka dym
ż
procesem jest zwi zana
ą
struktura, w której umieszczone są adresy procedur obs ugi
ł
sygna ów. Je li programista nie napisze w asnej funkcji obs uguj cej dany sygna , to
ł
ś
ł
ł
ą
ł
wykonywana jest procedura domy lna, która powoduje natychmiastowe zako czenie
ś
ń
procesu lub inne, zale ne
ż
od konfiguracji zachowanie. Część sygna ów
ł
mo na
ż
ignorowa ,
ć lub zablokować je na okre lony
ś
czas. Niektórych sygna ów
ł
nie mo na
ż
samemu obs u y , ani zignorowa , ani zablokowa (np. SIGKILL).
ł ż ć
ć
ć
4. Opis wa niejszych funkcji
ż
fork() - stwórz proces potomny. Funkcja ta zwraca dwie warto ci:
ś
dla procesu
macierzystego - PID potomka, dla procesu potomnego „0”. Je li
ś
jej wywo anie
ł
się nie powiedzie, to zwraca wartość „-1”. Oto fragment kodu, pozwalaj cy
ą
oprogramowa zachowanie potomka i rodzica:
ć
int porcpid = fork();
if(procpid == 0) {
/*tu kod potomka*/
} else {
3
/* tu kod rodzica*/
}
Szczegó y: man fork
ł
clone() - funkcja specyficzna dla Linuksa, s u y
ł ż do tworzenia nowego procesu.
Szczegó y: man clone
ł
getpid() i getppid() - funkcje zwracają odpowiednio: PID procesu bie
cego
żą
i PID jego rodzica. Szczegó y: man getpid
ł
sleep() - s u y
ł ż
do „u pienia”
ś
procesu na okre lon
ś
ą liczbę sekund. Szczegó y:
ł
man 3 sleep
wait - nie jest to jedna funkcja, ale rodzina funkcji (wait(), waitpid(), wait3(),
wait4()). Powodują one, e
ż
proces macierzysty czeka na zako czenie
ń
procesu
potomnego.
Status
zako czenia
ń
procesu
mo emy
ż
poznać
korzystaj c
ą
z odpowiednich makr. Szczegó y: man 2 wait.
ł
exit() - funkcja ko cz ca
ń ą
wykonanie procesu. Istnieje kilka innych podobnych
funkcji. Szczegó y: man 3 exit.
ł
exec – rodzina funkcji (execl(), execlp(), execle(), execv(), execv()), które zast puj
ę
ą
obraz w pami ci
ę
aktualnie wykonywanego procesu obrazem nowego procesu
odczytanym z pliku. Szczegó y: man 3 exec.
ł
kill() – funkcja powoduj ca wys anie sygna u o okre lonym numerze do procesu
ą
ł
ł
ś
o okre lonym PID. Szczegó y: man 2 kill.
ś
ł
signal() – funkcja pozwala okre li
ś ć zachowanie procesu, po otrzymaniu
odpowiedniego sygna u.
ł
Z tą funkcją powi zane
ą
są funkcje sigblock()
i sigsetmask().
W
chwili
obecnej
zalecane
jest
stosowanie
sigaction()
i sigprocmask(). Szczegó y:
ł
man signal, man sigblock, man sigsetmask, man
sigaction, man sigprocmask.
pause() – funkcja powoduje, e
ż proces czeka na otrzymanie sygna u.
ł
Szczegó y:
ł
man pause.
alarm() - pozwala ustawić czas, po którym proces otrzyma sygnał SIGALRM.
Szczegó y: man alarm.
ł
4
Zadania:
1. Napisz program, który utworzy dwa procesy: macierzysty i potomny. Proces
rodzicielski powinien wypisać swoje PID i PID potomka, natomiast proces potomny
powinien wypisa swoje PID i PID rodzica.
ć
2. Zademonstruj w jaki sposób mog powsta w systemie procesy zombie.
ą
ć
3. Napisz program, który stworzy dwa procesy. Proces macierzysty powinien poczekać
na wykonanie procesu potomnego i zbada status jego wyj cia.
ć
ś
4. Napisz program, który w zale no ci od warto ci argumentu podanego w linii polece
ż
ś
ś
ń
wygeneruje odpowiednią liczbę procesów potomnych, które b d
ę ą się wykonywa y
ł
wspó bie nie.
ł
ż
Ka dy
ż
z procesów potomnych powinien wypisać 4 razy na ekranie
swój PID, PID swojego rodzica oraz numer okre laj cy,
ś
ą
którym jest potomkiem
rodzica (1, 2, 3 ...), a nast pnie
ę
usnąć na tyle sekund, ile wskazuje ten numer
(pierwszy – 1 sekunda, 2 – dwie sekundy, trzeci - 3 sekundy). Proces macierzysty
powinien poczeka na zako czenie wykonania wszystkich swoich potomków.
ć
ń
5. Napisz dwa programy. Program pierwszy stworzy dwa procesy, a nast pnie
ę
proces
potomny zast pi procesem programu drugiego.
ą
6. Napisz program, który wy le do siebie sygna SIGALRM i obs u y go.
ś
ł
ł ż
7. Napisz program, który stworzy dwa procesy. Proces rodzicielski wy le
ś
do potomka
sygnał SIGINT (mo na
ż
go wys a
ł ć „r cznie”
ę
naciskaj c
ą na klawiaturze równocze nie
ś
Ctrl + C). Proces potomny powinien ten sygnał obs u y
ł ż ć za pomocą napisanej przez
Ciebie funkcji.
8. Napisz cztery osobne programy. Ka dy
ż
z nich powinien obs ugiwa
ł
ć wybrany przez
Ciebie sygna .
ł Ka dy
ż
z tych programów b dzie
ę
wysy a
ł ł co sekundę sygnał do innego
procesu, tzn. proces pierwszy b dzie
ę
wysy a
ł ł sygnał do procesu drugiego, drugi do
trzeciego, trzeci do czwartego, a czwarty do pierwszego.
Zak adamy,
ł
e
ż
procesy
b d
ę ą sterowane zdarzeniami, tzn. je li
ś
proces nie otrzyma sygna u
ł
to nic nie robi,
je li
ś otrzyma, to wypisuje na ekranie stosowny komunikat i wysy a
ł sygnał do innego
procesu. Jaki problem mo e
ż
się pojawić przy takiej wspó pracy
ł
procesów, jak mu
zapobiec?
9. Napisz program, który udowodni,
e
ż
obszar danych jest wspó dzielony
ł
mi dzy
ę
procesem potomnym i macierzystym do chwili wykonania modyfikacji danych przez
jednego z nich.
10. Ze wzgl dów
ę
bezpiecze stwa
ń
zaleca si ,
ę aby w ramach funkcji obs uguj cej
ł
ą
sygnał
wykonywane by y
ł
tylko proste czynno ci,
ś
jak np. ustawienie flagi informuj cej
ą
5
o otrzymaniu
sygna u,
ł
a skomplikowane
czynno ci
ś
eby
ż
by y
ł
wykonywane
w osobnym kodzie. Przedstaw schemat takiego rozwi zania
ą
stosuj c
ą
proces
macierzysty i potomny.
11. Poka w jaki sposób sygna y mog by przez proces blokowane lub ignorowane.
ż
ł
ą
ć
6