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