Semafory przypomnienie semafory służą ochronie dostępu procesów do sekcji krytycznej; na semaforach dostępne są dwie operacje: podniesienie semafora signal, opuszczenie semafora wait opuszczony semafor nie daje się już dalej opuścić i proces, który sobie tego życzy, musi poczekać, aż inny proces podniesie semafor; proces, korzystający z sekcji krytycznej chronionej przez semafor S: operacje prywatne procesu; wait(s); operacje w sekcji krytycznej; signal(s); operacje prywatne procesu; Wykład8,29IV2008,str.2 Potrzebny plik nagłówkowy #include"semafory.h": #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #include <sys/types.h> typedef int Semafor; typedef void* Wsp_pamiec; void blad(char* s); Semafor ustaw_semafor(key_t nazwa, int start); Semafor usun_semafor(semafor sem); void signal(semafor sem); void wait(semafor sem); Wsp_pamiec utworz_pamiec(key_t nazwa, int rozm);
Użycie pliku nagłówkowego w programie: gcc semafory.c moj_program.c W programie moj_program.c musi być dyrektywa #include"semafory.h" Wykład8,29IV2008,str.4 Deklaracja i inicjalizacja semafora: typedef int Semafor; Semafor ustaw_semafor(key_t nazwa, int start); wprowadza nowy semafor: nazwa nazwa semafora, start początkowa wartość(dla semafora binarnego: 1), wartość wynikowa identyfikator semafora do używania w programie. Przykład: MSemafor sem = ustaw_semafor((key_t)123, 1);
Usuwanie semafora: void usun_semafor(semafor sem); usuwa semafor: sem identyfikator semafora(wprowadzony przez ustaw_semafor()). Operacje na semaforze: void signal(semafor sem); void wait(semafor sem); podniesienie i opuszczenie semafora: signal(sem) podniesienie semafora sem, wait(sem) opuszczenie semafora sem. Przykład użycia semafora producent Wykład8,29IV2008,str.6 Semafor sem = ustaw_semafor((key_t)123, 1); p=produkuj();juz=0; do{ wait(sem); if(buforniejestpełny){ włóżpdobufora;juz=1; signal(sem); while(!juz);
Przykład użycia semafora konsument Semafor sem = ustaw_semafor((key_t)123, 1); juz=0; do{ wait(sem); if(buforniejestpusty){ wyjmijzbuforadop;juz=1; signal(sem); while(!juz); konsumuj(p); Lokalność zmiennych w procesie Wykład8,29IV2008,str.8 Musimy jeszcze zrealizować komendy wyżej nieformalnie opisane jako: buforniejestpusty, buforniejestpełny, włóżpdobufora, wyjmijzbuforadop. Każdy proces ma własną przestrzeń nazw, więc bufor zadeklarowany w jednym procesie będzie niedostępny w innym. Np. fragment programu int n=3; if(fork()){n++;printf("%i\n",n); else{n--;printf("%i\n",n); wydrukuje4i2 wartościdwóchróżnychzmiennychn. Jak zmusić konsumenta i producenta dopracynatymsamymbuforze?
Wspólna pamięć w Uniksie Deklaracja i inicjalizacja wspólnej pamięci: typedef void* Wsp_pamiec; Wsp_pamiec utworz_pamiec(key_t nazwa, int rozm); wprowadza nową wspólną pamięć: nazwa nazwa wspólnej pamięci, rozm liczba bajtów wspólnej pamięci, wartość wynikowa wskaźnik na utworzoną wspólną pamięć. Przykład: Mstruct dane_st{ int bufor[rozm_bufora]; int in; int out; ; struct dane_st* dane; Wsp_pamiec pam = utworz_pamiec((key_t)123, sizeof(*dane)); dane =(struct dane_st*)pam; Wspólna pamięć w Uniksie Wykład8,29IV2008,str.10 Operacje na wspólnej pamięci: poprzez pola struktury dane: dane->bufor dane->in dane->out