Instrukcja do laboratorium Systemów Operacyjnych
(semestr drugi)
wiczenie trzecie
Ć
Temat: Potoki i
cza nazwane w
łą
Linuksie.
Opracowanie:
mgr in . Arkadiusz Chrobot
ż
Wprowadzenie
1. Komunikacja z wykorzystaniem strumieni
W systemach uniksowych istnieje mo liwo
ż
ść utworzenia nowego procesu
realizuj cego
ą
wybrane
polecenie
pow oki
ł
i
stworzenia
dla
niego
cza
łą
komunikacyjnego za pomocą tyko jednego wywo ania
ł
funkcji. Tą funkcją jest
funkcja popen().
cze
Łą
utworzone przy jej pomocy jest jednokierunkowe, tzn.
proces wywo uj cy
ł
ą
mo e
ż
do niego pisać lub z niego czyta ,
ć ale nigdy te dwie
operacje nie są dost pne
ę
jednocze nie
ś
dla tego samego
cza.
łą
cze
Łą
nale y
ż
zamykać za pomocą funkcji pclose(). Jest ono wi zane
ą
ze standardowym
wej ciem
ś
lub wyj ciem
ś
polecenia, w zale no ci
ż
ś
od rodzaju operacji, czyli
domy lnie „zast puje” klawiatur lub ekran.
ś
ę
ę
2. Potoki
Inną formą komunikacji jednokierunkowej są potoki ( cza
łą
nienazwane), które
zwykle
s u
ł żą
do
wymiany
informacji
mi dzy
ę
dwoma
spokrewnionymi
procesami. Choć istnieje mo liwo
ż
ść u ywania
ż
potoku tylko w obr bie
ę
jednego
procesu, to nie jest to rozwi zanie,
ą
które stosuje się w praktyce. Potok tworzony
jest w przestrzeni j dra,
ą
ale poprzez wywo anie
ł
funkcji pipe() w przestrzeni
u ytkownika
ż
,
a
dost p
ę
do
niego
odbywa
się
przy
pomocy
funkcji
umo liwiaj cych
ż
ą
niskopoziomowe operacje na plikach – read() i write(). Ma on
sko czon
ń
ą
pojemno
,
ść
której
wielość
zale y
ż
od
konfiguracji
systemu.
W nowszych wersjach Linuksa (od 2.6.11) wynosi ona 64KiB. Dla utworzonego
potoku mo na
ż
ustawić znacznik O_NDELAY (O_NONBLOCK), który powoduje,
e
ż
program
nie
b dzie
ę
przechodził
w
stan
oczekiwania
w okre lonych
ś
sytuacjach, zwi zanych z obs ug potoku (szczegó y w
ą
ł
ą
ł
nast pnym punkcie).
ę
3.
cza nazwane, czyli kolejki FIFO
Łą
Kolejka jest podobna w dzia aniu
ł
do potoku, ale w przeciwie stwie
ń
do niego ma
nazw ,
ę a wi c
ę
mogą z niej korzystać procesy niespokrewnione. Kolejki FIFO
pojawi y
ł się w systemach uniksowych zgodnych ze wersją o nazwie System V
(w a ciwie
ł ś
to istnia y
ł
już od System III). Pierwotnie tworzono je za pomocą
funkcji mknod(), ale obecnie istnieje wygodniejsza w u yciu
ż
funkcja mkfifo().
Aby skorzystać z tak utworzonego
cza
łą
nazwanego nale y
ż go otworzyć albo do
zapisu, albo do odczytu (to samo ograniczenie co w przypadku potoku).
Dodatkowo
mo na
ż
zastosować
flagę
O_NDELAY
lub
to sam
ż
ą
jej
flagę
O_NONBLOCK. Powoduje to,
e
ż
proces nie b dzie
ę
czekał na zako czenie
ń
pewnych operacji zwi zanych z
ą
obs ug kolejki.
ł
ą
Dok adniej
ł
obja nia to poni sza
ś
ż
tabela:
2
Sytuacja
Nie ustawiono znacznika
O_NDELAY lub
O_NONBLOCK
Ustawiono O_NDELAY lub
O_NONBLOCK
Otwarto kolejkę tylko do
czytania, aden
ż
proces nie
otworzy jej do pisania.
ł
Oczekiwanie,
aż
proces
otworzy
kolejkę
do
pisania.
Natychmiastowy
powrót
bez sygnalizowania b du.
łę
Otwarto kolejkę tylko do
pisania,
aden
ż
proces nie
otworzy jej do czytania.
ł
Oczekiwanie,
aż
proces
otworzy kolejkę FIFO do
czytania.
Natychmiastowy
powrót
z sygnalizacją
b du
łę
w errno
(umieszczenie
sta ej ENXIO).
ł
Próba
czytania
danych
z kolejki,
je li
ś
nie
ma
w niej danych.
Oczekiwanie, aż pojawią
się dane lub nie b dzie
ę
ona otwarta do pisania
dla adnego
ż
procesu. Je li
ś
aden
ż
proces nie otworzy
kolejki do pisania funkcja
zwraca
wartość
zero,
w przeciwnym
wypadku
liczb oczytanych bajtów.
ę
Natychmiastowy
powrót,
wartość
funkcji
jest
równa zero.
Próba
zapisania
do
zape nionego cza FIFO.
ł
łą
Oczekiwanie,
aż
b dzie
ę
miejsce
do
zapisania
nowych danych.
Jak wy ej.
ż
Powy sza
ż
tabela odnosi się tak e
ż do potoków. Mo na
ż
również wyodr bni
ę
ć kilka
regu , którym podlega pisanie i czytanie do kolejek i potoków:
ł
•
Je li
ś
proces
da
żą
przeczytania mniejszej porcji danych niż wynosi bie
ca
żą
zawartość medium, to b dzie
ę
pobrane dok adnie
ł
tyle danych, ile za
dano.
żą
Reszta danych nie ulega zniszczeniu i mo e
ż być odczytana przy nast pnej
ę
operacji czytania.
•
Je li
ś
proces b dzie
ę
usi owa
ł
ł odczytać wi cej
ę
danych niż znajduje się
w medium, to odczytanych i tak zostanie tylko tyle danych, ile jest
w potoku lub kolejce.
•
Je li
ś
proces próbuje czytać z medium, które nie zosta o
ł
przez aden
ż
inny
proces otwarte do pisania, to wynikiem funkcji read() b dzie
ę
zero.
W przypadku kiedy ustawiony jest znacznik O_NDELAY nie mo na
ż
stwierdzi , czy medium by o puste, czy nie zosta o otwarte do zapisu.
ć
ł
ł
•
Zapis danych jest operacją niepodzieln ,
ą o ile proces zapisuje dane do
medium porcjami mniejszymi od jego pojemno ci,
ś
3
•
Je li
ś proces próbuje zapisywać do medium, które nie zosta o
ł otwarte przez
inny proces do odczytu, to otrzyma sygnał SIGPIPE, którego domy lna
ś
obs uga polega na zako czeniu procesu.
ł
ń
Po skorzystaniu z kolejki nale y
ż
ją usun
,
ąć aby nie zajmowa a
ł
miejsca na
dysku.
4. Opis wa niejszych funkcji
ż
•
popen()
- funkcja uruchamia polecenie pow oki
ł
podane w jej argumentach
wywo ania
ł
oraz tworzy strumień s u
cy
ł żą
do komunikacji mi dzy
ę
procesem
wywo anym
ł
a wywo uj cym,
ł
ą
który mo na
ż
obs ugiwa
ł
ć standardowymi
funkcjami fread() i fwrite(). Szczegó y: man 3 popen.
ł
•
fread()
- s u y
ł ż
do odczytu buforowanego ze strumienia. Szczegó y:
ł
man
3 fread.
•
fwrite()
- s u y
ł ż
do zapisu buforowanego do strumienia. Szczegó y:
ł
man
3 fwrite.
•
Funkcja pclose() - s u y
ł ż
do zamykania strumienia stworzonego przez
popen()
. Szczegó y: man 3 pclose.
ł
•
Funkcja pipe() - s u y
ł ż
do tworzenia potoku
cz cego
łą
ą
dwa spokrewnione
procesy. Jako argument wywo ania
ł
przyjmuje dwuelementową tablic ,
ę
w której b d
ę ą zapisane deskryptory potoku. Deskryptor zerowy jest do
odczytu, a pierwszy do zapisu. Zwykle jest ona wywo ywana
ł
przed fork(),
co powoduje, e
ż
procesy powsta e
ł
w wyniku podzia u
ł
odziedziczą tablicę
deskryptorów. Ka dy
ż
z tych procesów zamyka jeden z deskryptorów, np.
je li
ś
komunikacja przebiega wed ug
ł
schematu: rodzic -> potomek, to
rodzic zamyka deskryptor do odczytu, a potomek do zapisu. Szczegó y:
ł
man 2 pipe
•
Funkcja read() - czyta okre lon
ś
ą liczbę bajtów z deskryptora bez
buforowania. Szczegó y: man 2 read.
ł
•
Funkcja write() - zapisuje okre lon
ś
ą liczbę bajtów do deskryptora bez
buforowania. Szczegó y: man 2 write.
ł
•
Funkcja close() – zamyka deskryptor pliku. Do zamykania strumieni s u y
ł ż
fclose()
lub pclose(). Szczegó y: man 2 close.
ł
4
•
Funkcja mkfifo() - tworzy
cze
łą
nazwane o podanej nazwie i atrybutach,
mo e by zast piona przez
ż
ć
ą
mknod()
. Szczegó y: man 3 mkfifo
ł
•
Funkcja open() – otwiera plik (również
cze
łą
nazwane). Mo liwe
ż
jest dzi ki
ę
niej ustalenie trybu otwarcia i ustawienie znaczników. Szczegó y:
ł
man
2 open.
•
Funkcja fcntl() - s u y
ł ż
do manipulacji deskryptorem pliku. Mo na
ż
dzi ki
ę
niej ustawić flagę O_NDELAY (O_NONBLOCK) dla potoku. Szczegó y:
ł
man
2 fcntl.
•
Funkcja perror() – wypisuje wiadomość o b dzie
łę
zwróconą przez system.
Przyk ad u ycia: if(fork() < 0) perror(”fork:”); Szczegó y: man 3 perror.
ł
ż
ł
•
Funkcja unlink() – funkcja ta usuwa z systemu plików nazw ,
ę która mo e
ż
odnosić się do dowi zania
ą
lub pliku (ostatni przypadek odpowiada operacji
usuni cia
ę
pliku). Mo na
ż
ją wykorzystać do automatycznego usuwania
cza nazwanego. Szczegó y: man 2 unlink.
łą
ł
Zadania:
1. Napisz program, który wywo a
ł
polecenie „sort nazwa.c”, gdzie nazwa.c jest
nazwą pliku z kodem
ród owym
ź
ł
programu, a nast pnie
ę
odczyta 20 znaków
zwróconych przez to polecenie i wy wietli je na ekran.
ś
2. Napisz program, który uruchomi polecenie „wc” i przeka e
ż mu na standardowe
wej cie dowolny ci g znaków.
ś
ą
3. Napisz program, który stworzy potok, i wykorzysta go do przesy ania
ł
danych
w obr bie jednego procesu.
ę
4. Napisz program, który stworzy potok i wykorzysta go do komunikacji mi dzy
ę
dwoma spokrewnionymi procesami. Zadanie wykonaj dla dwóch przypadków:
z ustawion flag O_NDELAY (O_NONBLOCK) i bez.
ą
ą
5. Napisz program, który podzieli się na dwa procesy komunikuj ce
ą
się przy
pomocy potoków. Komunikacja musi by dwukierunkowa.
ć
6. Napisz dwa niezale ne
ż
programy, które b d
ę ą się komunikowa y
ł
przy pomocy
kolejki FIFO. Zadanie wykonaj w dwóch wariantach, tak jak zadanie 4. Po
zako czeniu komunikacji kolejk nale y usun
.
ń
ę
ż
ąć
7. Napisz program, w którym komunikacja mi dzy
ę
spokrewnionymi procesami
b dzie
ę
odbywa a
ł
się w jednym kierunku za pomocą
cza
łą
nienazwanego,
5
a w drugim za pomoc cza nazwanego.
ą łą
8. Stwórz programy do dialogu mi dzy
ę
dwoma u ytkownikami
ż
w systemie. Do
komunikacji u yj cza FIFO stworzonego za pomoc funkcji
ż
łą
ą
mknod.
9. Napisz program, który wygeneruje cztery procesy. Ka dy
ż
z tych procesów b dzie
ę
się komunikował z nast pnym
ę
za pomocą
cza
łą
nienazwanego. Pierwszy proces
wy le
ś
przez swoje
cze
łą
liczby 1,2,3 i 4. Ka dy
ż
kolejny zwi kszy
ę
ka d
ż ą z nich
o 1, a ostatni wypisze je na ekranie.
10. Napisz trzy programy komunikuj ce
ą
się przez
cza
łą
FIFO. Pierwszy program
b dzie
ę
wysy a
ł ł kolejne liczby parzyste, drugi kolejne liczby nieparzyste, a trzeci
b dzie
ę
odbierał te liczby i je sumowa .
ł Wszystkie procesy powinny wy wietla
ś
ć
wyniki pracy na ekranie.
6