lab11,12,13


SYSTEMY OPERACYJNE

Sprawozdanie z ćwiczeń laboratoryjnych nr 11,12,13

Prowadzący: dr hab. inż. Antoni Donigiewicz

Wykonał: Szymon Puacz I6Y2S1

I. Semafory

Semafory są strukturami danych wspólnie użytkowanymi przez kilka procesów. Najczęściej znajdują

one zastosowanie w synchronizowaniu działania kilku procesów korzystających ze wspólnego

zasobu, przez co zapobiegają niedozwolonemu wykonaniu operacji na określonych danych

jednocześnie przez większą liczbę procesów.

Z każdym semaforem z zestawu jest skojarzona struktura typu sem:

struct sem{

ushort semval // wartość semafora

pid_t sempid // identyfikator procesu ostatnio wykonującego operację na semaforze

ushort semncnt //liczba procesów, które czekają aż wartość semafora będzie zwiększona

ushort semzcnt //liczba procesów które czekają aż semafor osiągnie wartość 0

}

Funkcje umożliwiające synchronizację za pomocą semaforów zdefiniowane są w plikach

<sys/types.h>, <sys/ipc.h> oraz <sys/sem.h>.

Funkcje systemowe obsługujące zestawy semaforów i ich argumenty.

int semget (key_t key, int nsems, int semflags)

Wartości zwracane:

poprawne wykonanie funkcji: identyfikator zestawu semaforów

zakończenie błędne: -1

Argumenty funkcji:

key -liczba, która identyfikuje zestaw semaforów

nsems - liczba semaforów w zestawie, używana przez system podczas rezerwowania miejsca na

strukture sem, poindeksowana od 0

semflags - wskazuje prawa dostępu i/lub dodatkowe opcje dla tworzonego zestawu semaforów

( IPC_CREAT, IPC_EXCL, które połączone są operatorem OR)

UWAGI:

Utworzenie lub pobranie identyfikatora tablicy semaforów. Funkcja tworzy tablicę składającą się z

nsems semaforów, jeśli tablica o kluczu key jeszcze nie istnieje i zwraca na podstawie klucza

identyfikator tej tablicy. Parametr semflg umożliwia przekazanie praw dostępu do tablicy semaforów

oraz pewnych dodatkowych flag definiujących sposób jej tworzenia (np. IPC_CREAT), połączonych

z prawami dostępu operatorem sumy bitowej.

IPC_PRIVATE nie jest flagą tylko szczególną wartością key_t. Jeśli wartość ta zostanie użyta jako

wartość klucza, to system uwzględni jedynie bity uprawnień parametru msgflg i zawsze będzie

próbować utworzyć nową kolejkę.

int semctl (int semid, int semnum ,int cmd, union semun ctl_arg)

Wartości zwracane:

poprawne wykonanie funkcji: żądana wartość całkowita

zakończenie błędne: -1

Argumenty funkcji:

semid - identyfikator zestawu semaforów

semnum - liczba semaforów w zestawie

cmd - całkowitoliczbowa wartość reprezentująca polecenie

ctl_arg - w zależności od wykonywanej przez funkcję czynności jest to wskaźnik do struktury

semid_ds, lub adres bazowy tablicy liczb typu short int

UWAGI:

Zastosowania funkcji semctl:

ustawienie początkowej wartości semafora

zbadanie zmiany właściciela semafora, praw dostępu do niego, czasu ostatniej zmiany, ilości

procesów oczekujących na semafor i identyfikatora procesu ostatnio zmieniającego wartość

semafora, itd.

Operacje kontrolne na pojedynczym semaforze lub ich zestawie.

Drugim argumentem funkcji może być wartość 0, która pojawia się wówczas, gdy funkcja semctl ma

wykonać operację, podczas której liczba semaforów w zestawie nie ma znaczenia.

Wartość pola cmd może należeć do jednej z trzech grup:

1. tradycyjne operacje IPC

IPC_STAT - zwraca wartości struktury semid_ds dla semafora (lub zestawu) o identyfikatorze semid, informacja jest umieszczana w strukturze wskazywanej przez 4

argument funkcji semctl

IPC_SET - modyfikuje wartości struktury semid_ds

IPC_RMID - usuwa zestaw semaforów o identyfikatorze semid z systemu

2. operacje na pojedynczym semaforze (dotyczą semafora określonego przez semnum):

GETVAL - zwraca wartość semafora (semval), wskazywanego argumentem semnum

SETVAL - nadaje wartość określoną czwartym argumentem funkcji semaforowi o numerze

semnum

GETPID - zwraca wartość sempid

GETNCNT - pobranie liczby procesów oczekujących na to, aż semafor wskazywany przez

semnum zwiększy swoją wartość

GETZCNT - pobranie liczby procesów oczekujących na to, aż semafor wskazywany przez

semnum osiągnie wartość zero

3. operacje na wszystkich semaforach:

GETALL - pobranie bieżących parametrów całego zestawu semaforów i zapisanie

uzyskanych wartości w tablicy wskazanej czwartym argumentem funkcji

SETALL - zainicjowanie wszystkich semaforów z zestawu wartościami przekazanymi w

tablicy określonej przez wskaźnik przekazany czwartym argumentem funkcji

Ostatni argument funkcji jest unią:

union semun (

int val;

struct semid_ds *buf;

unsigned short *array

)

int semop (int semid, stuct sembuf *sops, unsigned nsops)

Wartości zwracane:

poprawne wykonanie funkcji: 0

zakończenie błędne: -1

Argumenty funkcji:

semid - identyfikator zestawu semaforów

sops - wskaźnik na adres bazowy tablicy operacji semaforowych, które zostaną wykonane na

zestawie semaforów określonym wartością semid

nsops - liczba elementów tablicy operacji semaforowych

UWAGI:

Wykonanie operacji semaforowej. Operacja semaforowa może być wykonywana jednocześnie na

kilku semaforach w tej samej tablicy identyfikowanej przez semid. Każdy element tablicy opisuje

jedną operację semaforową i ma następującą strukturę:

struct sembuf {

short sem_num; /* numer semafora - od 0 */

short sem_op; /* operacja semaforowa */

short sem_flg; /* flagi operacji */

};

Pole sem_op zawiera wartość, która zostanie dodana do zmiennej semaforowej pod warunkiem, że

zmienna semaforowa nie osiągnie w wyniku tej operacji wartości mniejszej od 0. Dodatnia liczba

całkowita oznacza zwiększenie wartości semafora (co z reguły oznacza zwolnienie zasobu), ujemna

wartość sem_op oznacza zmniejszenie wartości semafora (próbę pozyskania zasobu), a 0 -

testowanie, czy semafor jest równy 0, czyli czy wszystkie zasoby są zajęte.

Funkcja semop podejmuje próbę wykonania wszystkich operacji wskazywanych przez sops. Gdy

chociaż jedna z operacji nie będzie możliwa do wykonania nastąpi blokada procesu lub błąd

wykonania funkcji semop, zależnie od ustawienia flagi IPC_NOWAIT i żadna z operacji

semaforowych zdefiniowanych w tablicy sops nie zostanie wykonana. Flagi określają dodatkowe

cechy operacji (np. IPC_NOWAIT - jeżeli operacja na semaforze nie zostać przeprowadzona

wywołanie zostaje natychmiast zakończone, SEM_UNDO - jeżeli nie użyto znacznika

IPC_NOWAIT, umożliwia cofnięcie operacji blokującej która kończy sie parokrotnie

niepowodzeniem).

Pamięć współdzielona.

Pamięć współdzielona jest specjalnie utworzonym segmentem wirtualnej przestrzeni adresowej, do

którego dostęp może mieć wiele procesów. Jest to najszybszy sposób komunikacji pomiędzy

procesami.

Funkcje systemowe obsługujące pamięć współdzieloną i ich argumenty.

int shmget (key_t key, size_t size, int shmflags)

Wartości zwracane:

poprawne wykonanie funkcji: identyfikator segmentu pamięci współdzielonej

zakończenie błędne: -1

Możliwe kody błędów (errno) w przypadku błędnego zakończenie funkcji:

EACCES - brak brak praw dostępu

ENOENT - segment pamięci nie istnieje

EIDRM - segment pamięci został usunięty

EINVAL - nieprawidłowy rozmiar segmentu pamięci

ENOMEM - nie ma wystarczająco dużo miejsca by stworzyć segment pamięci współdzielonej

EEXIST - segment pamięci współdzielonej istnieje

Argumenty funkcji:

key - wartość klucza, który identyfikuje segment pamięci współdzielonej (podobnie jak w

przypadku kolejek komunikatów może to być dowolna liczba lub stała IPC_PRIVATE)

size - wielkość segmentu pamięci współdzielonej (w bajtach)

shmflags - prawa dostępu do pamięci współdzielonej (z prawami dostępu mogą zostać użyte

znaczniki IPC_CREAT, IPC_EXCL, ich działanie jest analogiczne jak w przypadku funkcji msgget)

UWAGI:

Funkcja shmget służy do tworzenia segmentu pamięci współdzielonej i do uzyskiwania dostępu fo

już istniejących segmentów pamięci. W drugim przypadku wartością parametru size może być 0,

ponieważ rozmiar segmentu został już wcześniej zadeklarowany przez proces, który go utworzył.

int shmctl (int shmid, int cmd, struct shmid_ds *buf)

Wartości zwracane:

poprawne wykonanie funkcji: 0

zakończenie błędne: -1

Argumenty funkcji:

shmid - identyfikator pamięci współdzielonej

cmd - stała specyfikująca rodzaj operacji

cmd = IPC_STAT - pozwala uzyskać informację o stanie pamięci współdzielonej

cmd = IPC_SET - pozwala zmienić parametry segmentu pamięci

cmd = IPC_RMID - pozwala usunąć segment pamięci współdzielonej z systemu

buf - wskaźnik na zmienną strukturalną przez którą przekazywane są parametry operacji

UWAGI:

Funkcja odpowiada funkcji msgctl. Przy próbie usunięcia segmentu odwzorowanego na przestrzeń

adresową procesu system odpowiada komunikatem o błędzie.

Jeśli w wywołaniu funkcji użyje się stałej IPC_RMID, to wartość argumentu buf należy wyzerować,

rzutując 0 na typ (shmid_ds *).

char* shmat (int shmid, char* shmaddr, int shmflg)

Wartości zwracane:

poprawne wykonanie funkcji: wskaźnik do segmentu danych, do którego jest dowiązana pamięć

współdzielona.

zakończenie błędne: -1

Argumenty funkcji:

shmid - identyfikator pamięci współdzielonej zwracany przez funkcję shmget

shmaddr - adres dla tworzonego segmentu pamięci współdzielonej lub wartość NULL, która

powoduje, że segment dołączany jest w miejscu wybranym przez system (użytkownik nie musi znać

rozmieszczenia programu w pamięci)

shmflg - określa uprawnienia do segmentu pamięci współdzielonej i specjalne warunki dowiązania

UWAGI:

Ponieważ pamięć jest alokowana przy wywołaniu funkcji shmat nie ma potrzeby używania funkcji

malloc przy umieszczaniu danych w segmencie.

Domyślnie dowiązane segmenty są dostępne w trybie do zapisu i odczytu. W przypadku gdy

segment ma segmentem tylko do odczytu, argument shmflg można połączyć operatorem OR ze

znacznikiem SHM_RDONLY. Natomiast gdy dla shmflg jest ustawiony znacznik SHM_RND, to

przy wywołaniu funkcji adres shmaddr jest zaokrąglany w dół do granicy strony w pamięci, a w

przeciwnym razie pobierana jest wartość podana jako argument wejściowy.

char* shmdt (char* shmaddr)

Wartości zwracane:

poprawne wykonanie funkcji: 0

zakończenie błędne: -1

Argumenty funkcji:

shmaddr - adres stworzonego segmentu pamięci współdzielonej

UWAGI:

Odłączenie segmentu pamięci współdzielonej. Odłączenie to powinno nastąpić po zakończeniu pracy

z danym segmentem. Po wywołaniu funkcji shmdt licznik dołączeń do segmentu jest zmniejszany o

1. Przykład usunięcia segmentu pamięci:

struct shmid_ds shm_desc;

shmctl(shm_id, IPC_RMID, shm_desc)

Wątki

Wątki określane są jako wydzielone sekwencje przewidzianych do wykonania instrukcji, które są

realizowane w ramach jednego procesu. Każdy wątek ma swój własny stos, zestaw rejestrów, licznik

programowy, indywidualne dane, zmienne lokalne, i informację o stanie. Wszystkie wątki danego

procesu mają jednak tę samą przestrzeń adresową., ogólną obsługę sygnałów, pamięć wirtualną,

dane oraz wejście-wyjście. W ramach procesu wielowątkowego każdy wątek wykonuje się

oddzielnie i asynchronicznie.

Funkcje systemowe służące do tworzenia wątków

pthread_create(pthread_t *thread, pthread_attr_t *attr, void*

(*start_routine) (void*),void *arg)

utworzenie wątku. Wątek wykonuje funkcję wskazywaną przez parametr start_routine.

Parametry funkcji muszą być przekazane przez wskaźnik na obszar pamięci (strukturę),

który zawiera odpowiednie wartości. Wskaźnik ten jest przekazywany przez parametr arg i

jest dalej przekazywany jako parametr aktualny do funkcji wykonywanej przez wątek.

Parametr attr wskazuje na atrybuty wątku, a przez wskaźnik thread zwracany jest

identyfikator wątku.

pthread_exit(void *retval)

zakończenie wątku. Funkcja powoduje zakończenie wątku i przekazanie retval, jako

wskaźnika na wynik. Wskaźnik ten może zostać przejęty przez inny wątek, który będzie

wykonywał funkcję pthread_join.

pthread_join(pthread_t th, void **thread_return)

oczekiwanie na zakończenie wątku. Funkcja umożliwia zablokowanie wątku w oczekiwaniu

na zakończenie innego wątku, identyfikowanego przez parametr th. Jeśli oczekiwany wątek

zakończył się wcześniej, funkcja zakończy się natychmiast. Funkcja przekazuje przez

parametr thread_return wskaźnik na wynik wątku (wykonywanej przez niego funkcji),

przekazany jako parametr funkcji pthread_exit wywołanej w zakończonym wątku.

pthread_cancel(pthread_t thread)

zakończenie wykonywania innego wątku. Funkcja umożliwia wątkowi usunięcie z systemu

innego wątku, identyfikowanego przez parametr thread.

III. Funkcje systemowe służące do synchronizacji wątków

1) Wzajemne wykluczanie:

Do zapewnienia wzajemnego wykluczania używana jest zmienna (o przykładowej nazwie mutex),

zadeklarowana następująco:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(pthread_mutex_t *mutex)

zajęcie zamka. Funkcja powoduje zajęcie zamka wskazywanego przez parametr mutex,

(zajęcie sekcji krytycznej) poprzedzone ewentualnym zablokowaniem wątku do czasu

zwolnienia zamka, jeśli został on wcześniej zajęty przez inny wątek.

pthread_mutex_unlock(pthread_mutex_t *mutex)

zwolnienie zamka. Funkcja powoduje zwolnienie zamka wskazywanego przez parametr

mutex (zwolnienie sekcji krytycznej), umożliwiając jego zajęcie innemu wątkowi.

pthread_mutex_trylock(pthread_mutex_t *mutex) —

próba zajęcia zamka. Funkcja powoduje zajęcie zamka wskazywanego przez parametr

mutex, jeśli nie jest zajęty przez inny wątek. W przeciwnym przypadku zwraca błąd, nie

blokując tym samym procesu.

2) Zmienne warunkowe

Synchronizacja za pomocą zmiennych warunkowych polega na usypianiu i budzeniu wątku w sekcji

krytycznej. W tym celu używana jest zmienna warunkowa (o przykładowej nazwie cond),

zadeklarowana następująco:

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

oczekiwanie na sygnał. Funkcja powoduje uśpienie wątku na zmiennej warunkowej,

wskazywanej przez parametr cond. Na czas uśpienia wątek zwalnia zamek, wskazywany

przez parametr mutex, udostępniając tym samym sekcję krytyczną innym wątkom. Po

obudzeniu i wyjściu z funkcji (na skutek odebraniu sygnału wysłanego przez

pthread_cond_signal) zamek zajmowany jest ponownie.

pthread_cond_signal(pthread_cond_t *cond)

wysłanie sygnału (obudzenie) do jednego z oczekujących na zmiennej warunkowej

wskazywanej przez cond.

2



Wyszukiwarka

Podobne podstrony:
12,13 żywienie dzieci w wieku szkolnymid 13394 ppt
Medycyna laboratoryjna 12 13
Geometria wykreślna Ćwiczenie 12 13
Liga zadaniowa 12 (12-13) - odpowiedzi, Liga zadaniowa
NAUKA O POLITYCE 12 13
system oświaty 12 13
wykłady do 11 12 13
badop Zarz niestac IIst 12 13 zima zadania
piae wyklad2 12 13
EZNiOS Log 12 13 w8 kryzys slajdy
2010 12 13 prawdopodobie stwo i statystykaid 27016
EZNiOS Log 12 13 w4 pojecia id Nieznany
audytoria 9 12 1 13
piae wyklad3 12 13 id 356381 Nieznany
13a funkcje zarzadzania w aspekcie zasobów inf, Procesy informacyjne w zarządzaniu, materiały studen
bud1 12 13
Liga zadaniowa 5 (12-13), Liga zadaniowa
Powiedzmy z dumą Nasz Kościół broni godności człowieka - [2008-12-13], bioetyka

więcej podobnych podstron