API us lug jadra systemu operacyjnego UNIX∗
,
Dariusz Wawrzyniak
darek@cs.put.poznan.pl
18 stycznia 2000
Wszystkie opisane niżej funkcje z wyjatkiem funkcji z bi-execlp(const char* file, const char* arg, ...) —
,
blioteki pthread (patrz punkt 2) w przypadku b ledu zwra-funkcja dzia la podobnie jak execl, jednak plik z pro-
,
caja wartość -1, w zwiazku z czym fakt ten nie jest wyszcze-gramem poszukiwany jest w katalogach wyszczególnio-
,
,
gólniony przy opisie poszczególnych funkcji.
nych w zmiennej środowiskowej PATH.
Analogiczne jest dzia lanie funkcji systemowych execv i 1
Procesy
execvp.
Różnica jest w przekazywaniu parametrów: w
przypadku funkcji execv/execvp parametry przekazywane W odniesieniu do procesów wymagana jest znajomość na-sa przez tablice stringów.
,
,
stepujacych terminów i zagadnień: proces, hierarchia pro-
,
,
cesów i sposoby ich identyfikacji (identyfikator procesu —
2
Watki
pid, identyfikator procesu macierzystego — ppid, efektywny
,
identyfikator użytkownika/grupy i rzeczywisty identyfikator Wymagana jest znajomość zagadnień dostepu watków użytkownika/grupy), proces systemowy init, program wyko-
,
,
do wspó ldzielonej przestrzeni adresowej, szczególnie zasad nywany przez proces, proces macierzysty, proces potomny, wspó ldzielenia segmentu danych i segmentu stosu.
proces-sierota, adoptowanie sierot, proces-zombi.
Funkcje opisane w tym punkcie zwracaja wartość 0 w
,
przypadku poprawnego zakończenia lub kod b ledu, który fork() — utworzenie procesu potomnego. W procesie ma-
,
jest wartościa różna od 0.
cierzystym funkcja zwraca identyfikator (pid) procesu
,
,
potomnego (wartość wieksza od 0, w praktyce wieksza
,
,
,
,
od 1), a w procesie potomnym wartość 0.
2.1
Tworzenie watków
,
pthread_create(pthread_t *thread,
pthread_attr_t
exit(int status) — zakończenie procesu. Funkcja koń-
czy proces i powoduje przekazanie w odpowiednie miej-
*attr,
void*
(*start_routine)
(void*),
atku.
Watek wykonuje
sce tablicy procesów wartości status, która może zostać void *arg) — utworzenie w ,
,
funkcje wskazywana przez parametr start routine.
odebrana i zinterpretowana przez proces macierzysty.
,
,
Parametry funkcji musza być przekazane przez wskaź-
,
wait(int *status) — oczekiwanie na zakończenie po-nik na obszar pamieci (strukture), który zawiera
,
,
tomka.
Funkcja zwraca identyfikator (pid) procesu,
odpowiednie wartości. Wskaźnik ten jest przkazywany który sie zakończy l. Pod adrsem wskazywanym przez przez parametr arg i jest dalej przekazywany jako
,
status umieszczany jest status zakończenia, który za-paremetr aktualny do funkcji wykonywanej przez wiera albo numer sygna lu (najmniej znaczace 7 bitów), watek.
Parametr attr wskazuje na atrybuty watku,
,
,
,
albo status w laściwy (bardziej znaczacy bajt). Naj-a przez wskaźnik thread zwracany jest identyfikator
,
bardziej znaczacy bit m lodszego bajtu wskazuje, czy watku.
,
,
nastapi l zrzut core’a.
,
pthread_exit(void *retval)
—
zakończenie
watku.
,
Funkcja powoduje zakończenie watku i przekazanie execl(const char* path, const char* arg, ...)
—
,
retval, jako wskaźnika na wynik. Wskaźnik ten może zmiana programu wykonywanego przez proces. Proces zostać przejety przez inny watek, który bedzie wyko-rozpoczyna wykonywanie nowego programu, którego
,
,
,
nywa l funkcje
kod znajduje sie w pliku wskazywanym przez path.
pthread_join.
,
,
Jeśli path nie jest ścieżka abosolutna, to znaczy, że
,
,
pthread_join(pthread_t th, void **thread_return) ścieżka rozpoczyna sie od katalogu bieżacego. Pomimo
,
,
— oczekiwanie na zakńczenie watku. Funkcja umożli-
,
zmiany wykonywanego programu pewne atrybuty
wia zablokowanie watku w oczekiwaniu na zakończenie
,
procesu (pid, ppid, tablica otwartych plików) nie innego watku, identyfikowanego przez parametr th.
,
ulegaja zmianie.
,
Jeśli oczekiwany watek zakończy l sie wcześniej, funk-
,
,
∗W przypadku wykrycia jakichkolwiek b ledów prosze o mail na cja zakończy sie natychmiast.
Funkcja przekazuje
,
,
,
podany adres.
przez parametr thread return wskaźnik na wynik 1
watku (wykonywanej przez niego funkcji), przekazany watków. Funkcja powoduje wys lanie sygna lu do jed-
,
,
jako parametr funkcji pthread_exit wywo lanej w nego z watków śpiacych na zmiennej warunkowej wska-
,
,
zakończonym watku.
zywanej przez cond w celu obudzenia. Jeśli na wskaza-
,
nej zmiennej warunkowej nie śpi żaden watek, sygna l
,
pthread_cancel(pthread_t thread) — zakończenie wy-ginie bez żadnego efektu.
konywania innego watku. Funkcja umożliwia watkowi
,
,
usuniecie z systemu innego watku, identyfikowanego pthread_cond_broadcast(pthread_cond_t *cond)
—
,
,
przez parametr thread.
wys lanie sygan lu (obudzenie) do wszystkich oczekujacych watków.
Funkcja dzia la podobnie jak
,
,
pthread_cond_signal
z taka różnica,
że sygna l
2.2
Synchronizacja watków
,
,
,
budzacy wysy lany jest do wszystkich watków śpiacych
,
,
,
2.2.1
Wzajemne wykluczanie
na zmiennej warunkowej wskazywanej przez cond.
Do zapewnienia wzajemnego wykluczania używana jest zmienna (o przyk ladowej nazwie mutex), zadeklarowana na-3
Pliki
stepujaco:
,
,
Wymagana jest znajmość zasad tworzenia i dostepu do pli-
,
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ków w hierachicznej strukturze katalogów.
pthread_mutex_lock(pthread_mutex_t *mutex) — zaje-
,
3.1
Tworzenie i otwieranie plików
cie zamka. Funkcja powoduje zajecie zamka wskazy-
,
wanego przez parametr mutex. (zajecie sekcji krytycz-creat(const char *pathname, mode_t mode) — utwo-
,
nej) poprzedzone ewentualnym zablokowaniem watku rzenie nowego pliku lub usuniecie jego zawartości, gdy
,
,
do czasu zwolnienia zamka, jeśli zosta l on wcześniej za-już istnieje oraz otwarcie go do zapisu. Funkcja tworzy jety przez inny watek.
plik, którego lokalizacje wskazuje parametr pathname.
,
,
,
Prawa dostepu do utworzonego pliku ustawiane sa
,
,
pthread_mutex_unlock(pthread_mutex_t *mutex)
—
zgodnie z parametrem mode. Jeśli plik o takiej na-zwolnienie zamka.
Funkcja powoduje zwolnienie
zwie już istnieje, a proces wywo lujacy funkcje creat
,
,
zamka wskazywanego przez parametr mutex (zwol-
ma prawo do zapisu tego pliku, to jego zawartość jest nienie sekcji krytycznej), umożliwiajac jego zajecie usuwana. Plik wskazywany przez pathname otwierany
,
,
innemu watkowi.
jest w trybie do zapisu, a funkcja zwraca jego deskryp-
,
tor.
pthread_mutex_trylock(pthread_mutex_t *mutex)
—
próba zajecia zamka. Funkcja powoduje zajecie zamka open(const char *pathname, int flags)
— otwarcie
,
,
wskazywanego przez parametr mutex, jeśli nie jest pliku. Funkcja otwiera plik o nazwie pathname w try-zajety przez inny watek. W przeciwnym przypadku bie okrślonym przez parametr f lags (np. O_WRONLY,
,
,
zwraca b lad, nie blokujac tym samym procesu.
O_RDONLY, O_RDWR). Funkcja zwraca deskryptor otwar-
,
,
tego pliku.
2.2.2
Zmienne warunkowe
close(int fd) — zamkniecie deskryptora pliku. Funkcja
,
zamyka deskryptor pliku przekazany przez parametr Synchronizacja za pomoca zmiennych warunkowych polega
,
f d. Jeśli jest to ostatni (jedyny) deskryptor pliku, na-na usypianiu i budzeniu watku w sekcji krytycznej. W tym
,
stepuje zamkniecie pliku.
celu używana jest zmienna warunkowa (o przyk ladowej na-
,
,
zwie cond), zadeklarowana nastepujaco:
dup(int oldfd) — powielenie deskryptora. Funkcja powo-
,
,
duje utworzenie dodatkowego deskryptora otwartego pthread_cond_t cond = PTHREAD_COND_INITIALIZER; wcześniej pliku, identyfikowanego przez parametr (deskryptor) oldf d.
Nowy deskryptor tworzony jest na
pthread_cond_wait(pthread_cond_t *cond,
pierwszej wolnej pozycji (otrzymuje najmniejsza moż-
,
pthread_mutex_t *mutex) — oczekiwanie na sy-
liwa wartość). Funkcja zwraca wartość nowo utworzo-
,
gna l. Funkcja powoduje uśpienie watku na zmiennej
,
nego deskryptora.
warunkowej, wskazywanej przez parametr cond.
Na
czas uśpienia watek zwalnia zamek, wskazywany przez dup2(int oldfd, int newfd) — powielenie deskryptora
,
parametr mutex, udostepniajac tym samym sekcje we wskazanym miejscu.
Podobnie jak w przypadku
,
,
,
krytyczna innym watkom.
Po obudzeniu i wyjściu
funkcji dup, tworzony jest nowy deskryptor otwartego
,
,
z funkcji (na skutek odebraniu sygna lu wys lanego pliku, identyfikowanego przez oldf d, w miejscu wska-przez pthread_cond_signal) zamek zajmowany jest zanym przez newf d. newf d staje sie nowym, dodat-
,
ponownie.
kowym deskryptorem, a jeśli przed wywo laniem dup2
identyfikowa l on inny otwarty plik, nastepuje zamknie-
,
,
pthread_cond_signal(pthread_cond_t *cond) — wy-cie tego deskryptora przed powieleniem oldf d. Funkcja s lanie sygan lu (obudzenie) do jednego z oczekujacych zwraca wartość nowego deskryptora.
,
2
unlink(const char *pathname) — usuniecie dowiazania 4.2
Tworzenie i otwieranie klejek FIFO
,
,
do pliku.
Funkcja usuwa wskazana przez parametr
,
( laczy nazwanych)
,
pathname nazwe pliku, a jeśli by lo to jedyne dowia-
,
,
zanie tego pliku, nastepuje usuniecie pliku z systemu.
mkfifo(const char *pathname, mode_t mode) — utwo-
,
,
rzenie kolejki FIFO. Funkcja tworzy (ale nie otwiera) plik typu kolejka FIFO w katalogu i pod nazwa zawarta
,
,
3.2
Operacje na plikach
w parametrze pathname, z prawami dostepu przekaza-
,
nymi w parametrze mode.
read(int fd, void *buf, size_t count) — odczyt z pliku. Funkcja powoduje odczyt count bajtów z otwar-open(const char *pathname, int flags)
— otwarcie
tego pliku, identyfikowanego przez deskryptor f d, po-kolejki FIFO. Funkcja otwiera kolejke FIFO o na-czawszy od bieżacej pozycji i umieszczenie ich pod ad-
,
,
,
zwie wskazanej przez pathname, podobnie jak otwie-resem buf w przestrzeni adresowej procesu. Funkcja rany jest plik. Kolejka może być otwierana tylko w zwraca liczbe bajtów, na której uda lo sie wykonać ope-
,
,
dwóch trybach: tylko do odczytu (f lags = O_RDONLY) racje.
,
lub tylko do zapisu (f lags = O_WRONLY). Ponadto kolejka musi zostać otwarta w trybie komplementarnym, write(int fd, const void *buf, size_t count)
—
tzn. musza być dwa procesy, z których jeden otwiera zapis do pliku. Funkcja powoduje zapis count bajtów,
,
kolejke w trybie O_RDONLY, a drugi w trybie O_WRONLY.
poczawszy od bieżacej pozycji, w otwartym pliku
,
,
,
W przeciwnym razie jeden z procesów jest blokowany.
identyfikowanym przez deskryptor f d.
Zapisywane
Funkcja zwraca deskryptor kolejki.
wartości pobierane sa spod adresu buf w przestrzeni
,
adresowej procesu. Funkcja zwraca liczbe bajtów, na
,
której uda lo sie wykonać operacje.
,
,
4.3
Operacje na laczach
,
lseek(int fd, off_t offset, int whence) — przesu-read(int fd, void *buf, size_t count) — odczyt z niecie wskaźnika bieżacej pozycji. Funkcja powoduje lacza. Dane z lacza sa odczytywane tak, jak z pliku.
,
,
,
,
,
zmiane wskaźnika bieżacej pozycji w otwartym pliku.
Jeśli lacze jest puste, ale jest otwarty jakiś deskryp-
,
,
,
Nowa pozycja jest bajtem o numerze of f set liczonym tor do zapisu (potencjalnie w potoku moga pojawić sie
,
,
odpowienio wzgledem
jakieś dane), to proces jest blokowany. Jeśli danych
,
jest mniej niż wartość parametru count, odczytane zo-
• poczatku pliku, gdy whence = SEEK_SET,
stana tylko dostepne dane. Dane beda odczytywane w
,
,
,
,
,
kolejności, w której zosta ly zapisane, a po odczytaniu
• końca pliku, gdy whence = SEEK_END,
zostana usuniete z lacza.
,
,
,
• bieżacej pozycji, gdy whence = SEEK_CUR.
,
write(int fd, const void *buf, size_t count)
—
Wartość parametru of f set < 0 oznacza przesuniecie w zapis do lacza. Dane zapisywane sa tak, jak w przy-
,
,
,
kierunku poczatku pliku (niższych indeksów), a war-padku zapisu w pliku, z wyjatkiem sytuacji, gdy brak
,
,
tość of f set > 0 oznacza przesuniecie w kierunku końca jest wystarczajacej ilości wolnego miejsca. Wówczas
,
,
pliku (wyższych indeksów). Funkcja zwraca aktualna proces jest blokowany.
Funkcja zapisze w potoku
,
wartość wskaźnika bieżacej pozycji (po przesunieciu), count bajtów w ca lości i beda one stanowi ly ciag ly
,
,
,
,
,
liczona wzgledem poczatku pliku.
strumień danych (nie beda sie przeplatać z danymi
,
,
,
,
,
,
pochodzacymi z innych zapisów (innych wywo lań
,
funkcji write).
4
Lacza (potoki i kolejki FIFO)
,
close(int fd) — zamkniecie deskryptora lacza. Funkcja
,
,
Wymagana jest znajomość zagadnień komunikacji strumie-dzia la analogicznie, jak w przypadku zamykania de-niowej, w szczególności różnicy pomiedzy komunikacja stru-skryptora zwyk lego pliku.
,
,
mieniowa a komunikacja pakietowa”.
,
, ”
,
5
Mechanizmy IPC
4.1
Tworzenie i otwieranie potoków ( laczy
,
nienazwanych)
5.1
Pamieć wspó ldzielona
,
pipe(int filedes[2]) — utworzenie potoku i otwarcie shmget(key_t key, int size, int shmflg) — utworze-go do zapisu i do odczytu. Funkcja tworzy i zarazem nie lub pobranie identyfikatora segmentu pamieci
,
otwiera potok, i przekazuje przez tablice f iledes dwa
,
wspó ldzielonej.
Funkcja tworzy segment wspó ldzie-
deskryptory. f iledes[0] zawiera deskryptor potoku do lonej pamieci o rozmiarze size, identyfikowany przez
,
odczytu, a f iledes[1] zawiera deskryptor potoku do za-klucz key lub znajduje segment o takim kluczu, je-pisu.
śli segment już istnieje. Funkcja zwraca identyfikator, 3
który s luży do odwo lywanie sie do segmentu w pozo-procesu lub b lad wykonania funkcji semop, zależnie od
,
,
sta lych funkcjach operujacych na pamieci wspó ldzie-ustawienia flagi IPC_NOWAIT i żadna z operacji sema-
,
,
lonej. Parametr shmf lg umożliwia przekazanie praw forowych zdefiniowanych w tablicy sops nie zostanie dostepu do kolejki oraz pewnych dodatkowych flag de-wykonana. sem_op = 0 oznacza oczekiwanie na osia-
,
,
finiujacych sposób jej tworzenia (np. IPC_CREAT), po-gniecie wartości 0 przez zmienna semaforowa. Flagi
,
,
,
,
laczonych z prawami dostepu operatorem sumy bitowej określaja dodatkowe cechy operacji (np. IPC_NOWAIT,
,
,
,
(np. IPC_CREAT|0660).
SEM_UNDO).
shmat(int shmid, const void *shmaddr, int shmflg) semctl(int semid, int semnum, int cmd,
— w laczenie segmentu pamieci wspó ldzielonej w union semun arg)
— operacje kontrolne na ta-
,
,
przestrzeń adresowa procesu. Funkcja przydziela seg-blicy semaforów.
,
mentowi wspó ldzielonej pramieci, identyfikowanemu
,
przez shmid, adres w przestrzeni adresowej procesu i 5.3
Kolejki komunikatów
zwraca ten adres jako wynik.
msgget(key_t key, int msgflg) — utworzenie lub po-shmdt(const void *shmaddr) — wy laczenie segmentu pa-
,
branie identyfikatora kolejki komunikatów.
Funkcja
mieci wspó ldzielonej z przestrzeni adresowej procesu.
,
tworzy kolejke komunikatów, jeśli kolejka o kluczu key
,
Funkcja powoduje od laczenie segmentu pamieci wspó l-
,
,
jeszcze nie istnieje, i zwraca identyfikator tej kolejki.
dzielonej, umieszczeonego pod adresem shmaddr.
Parametr msgf lg umożliwia przekazanie praw dostepu
,
do kolejki oraz pewnych dodatkowych flag definiuja-shmctl(int shmid, int cmd, struct shmid_ds *buf)
,
cych sposób jej tworzenia (np. IPC_CREAT), po laczo-
— operacje kontrolne na segmencie pamieci wspó l-
,
,
nych z prawami dostepu operatorem sumy bitowej (np.
dzielonej.
Funkcja umożliwia wykonywanie operacji
,
IPC_CREAT|0660).
kontrolnych na segmencie pamieci wspó ldzielonej, np.
,
usuniecie tego segmentu.
,
msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg) — wys lanie komunikatu przez przekaza-5.2
Semafory
nie go do kolejki. Funkcja umieszcza w kolejce identyfikowanej przez msgid komunikat, którego treść znaj-semget(key_t key, int nsems, int semflg) — utwoduje sie pod adresem msgp w przestrzeni adresowej
,
rzenie lub pobranie identyfikatora tablicy semaforów.
procesu i zawiera msgsz bajtów we w laściwej treści Funkcja tworzy tablice sk ladajaca sie z nsems sema-
,
,
,
,
komunikatu oraz wartość typu long określajaca typ ko-
,
,
forów, jeśli tablica o kluczu key jeszcze nie istnieje i munikatu. Ogólna struktura komunikatu zdefiniowana zwraca na podstawie klucza identyfikator tej tablicy.
jest nastepujaco:
,
,
Parametr semf lg umożliwia przekazanie praw dostepu
,
do tablicy semaforów oraz pewnych dodatkowych flag struct msgbuf {
definiujacych sposób jej tworzenia (np. IPC_CREAT),
,
long mtype;
/* typ komunikatu, > 0 */
po laczonych z prawami dostepu operatorem sumy bi-
,
,
char mtext[1];
/* treść komunikatu */
towej (np. IPC_CREAT|0660).
};
semop(int semid, struct sembuf *sops,
Treść komunikatu może mieć w rzeczywistości inny roz-unsigned nsops)
—
wykonanie
operacji
semfo-
miar i inna strukture.
Jeśli w kolejce nie ma miej-
rowej.
Operacja semaforowa może być wykonywana
,
,
sca to proces jest blokowany w funkcji msgsnd lub w jadnocześnie na kilku semaforach w tej samej tablicy przyapadku ustawienia flagi IPC_NOWAIT w parametrze identyfikowanej przez semid.
sops jest wskaźnikiem
msgf lg zwracana jest wartość -1.
na tablice operacji semaforowych, a nsops jest liczba
,
,
elementów w tej tablicy.
Każdy element tablicy
msgrcv(int msqid, struct msgbuf *msgp, int msgsz, opisuje jedna operacje semaforowa i ma nastepujaca
,
,
,
,
,
,
long msgtyp, int msgflg) — odebranie komunikatu strukture:
,
przez pobranie go z kolejki.
Funkcja pobiera z ko-
lejki komunikat który spe lnia kryteria określone przez struct sembuf {
msgtyp (typ komunikatu), pmsgsz (rozmiar bufora w short sem_num;
/* numer semafora */
przestrzeni adresowej procesu) i msgf lg (flagi specy-short sem_op;
/* operacja semaforowa */
fikujace zachowanie sie funkcji w warunkach ńietypo-
,
,
short sem_flg;
/* flagi operacji */
wych”). Wybór komunikatu dokonuje sie wed lug naste-
,
,
};
pujacych zasad: jeśli parametr msgf lg ma ustawiona
,
,
flage MSG_NOERROR, komunikat przekraczajacy rozmiar
,
,
Pole sem_op zawiera wartość, która zostanie dodana bufora jest ucinany przy odbiorze. W przeciwnym ra-do zmiennej semaforowej pod warunkiem, że zmienna zie odbierane sa tylko komunikaty, których treść ma
,
semaforowa nie osiagnie w wyniku tej operacji wartości mniejszy rozmiar niż msgsz. Drugim kryterium wy-
,
mniejszej od 0. W przeciwnym razie nastapi blokada boru jest typ komunikatu, zgodnie z poniższa regu la:
,
,
,
4
• msgtyp > 0 — wybierany jest komunikat, którego typ jest dok ladnie taki, jak msgtyp,
• msgtyp < 0 — wybierany jest komunikat, którego który ma najmniejsza wartość typu mniejsza lub
,
,
równa bezwzglednej wartości z msgtyp,
,
,
• msgtyp = 0 — typ komunikatu nie jest brany pod uwage przy wyborze.
,
Komunikaty spe lniajace kryteria pobierane sa w kolej-
,
,
ności, w której zosta ly umieszczone w kolejce. Jeśli w kolejce nie ma wymaganego komunikatu i w parametrze f lag ustawiona jest flaga IPC_NOWAIT, funkcja zwraca
-1. Jeśli flaga nie jest ustawiona, proces jest blokowany aż do czasu pojawienia sie komunikatu. Funkcja
,
zwraca rozmiar treści odebranego komunikatu (liczbe, bajtów zajmowana przez mtext).
,
msgctl(int msqid, int
cmd, struct msqid_ds *buf)
— operacje kontrolne na kolejce komunikatów.
6
Sygan ly
void (*signal(int signum,
void (*handler)(int)))(int)
—
zdefiniowanie
sposobu reakcji procesu na sygna l. Funkcja umożliwia ustawienie ignorowania sygna lu o numerze signum (jako handler przekazywana jest sta la SIG_IGN), ustawienie domyślnej reakcji (jako handler przekazywana jest sta la SIG_DFL) lub przechwytywanie sygna lu. W
przypadku przechwytywania jako wartość aktualna parametru handler przekazywany jest wskaźnik na funkcje, która bedzie wywo lywana asynchronicznie
,
,
w reakcji na otrzymanie sygna lu signum.
Funkcja
zwraca
wzkaźnik
na
poprzednia
funkcja
obs lugi
,
,
sygna lu lub odpowiednia sta la (SIG_DFL, SIG_IGN).
,
,
kill(pid_t pid, int signum) — wys lanie sygna lu do procesu. Funkcja powoduje wys lanie sygan lu signum do procesu o identyfikatorze pid.
5