J. Ułasiewicz Programowanie aplikacji współbieżnych 1



Podobne dokumenty
Rys. 9-1 Procesy P1 i P2 komunikuję się poprzez wspólny obszar. pamięci.

J. Ułasiewicz Programowanie aplikacji współbieżnych 1

J. Ułasiewicz Programowanie aplikacji współbieżnych 1

10. Synchronizacja użycia zasobów, Semafory Problem producenta i konsumenta

10. Synchronizacja użycia zasobów, Semafory

Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011

Dziedziczenie : Dziedziczenie to nic innego jak definiowanie nowych klas w oparciu o już istniejące.

Pamięć współdzielona

Semafory, pamięć dzielona i kolejki komunikatów

10. Synchronizacja użycia zasobów, Semafory

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

10. Synchronizacja użycia zasobów, Semafory

Obsługa plików Procesy

Ćwiczenia IV - Kontenery (pojemniki)

Tworzenie wielopoziomowych konfiguracji sieci stanowisk asix z separacją segmentów sieci - funkcja POMOST. Pomoc techniczna

Pliki. Funkcje tworzące pliki i operujące na nich opisane są w części 2 pomocy systemowej. Tworzenie i otwieranie plików:

Bazy danych II. Andrzej Grzybowski. Instytut Fizyki, Uniwersytet Śląski

Instytut Teleinformatyki

Zad.1 Pokazać pierwszeństwo trybu odmów przed zezwalaj.

Projektowanie bazy danych

Bazy danych. Andrzej Łachwa, UJ, /15

PERSON Kraków

Konfiguracja historii plików

Instalacja. Zawartość. Wyszukiwarka. Instalacja Konfiguracja Uruchomienie i praca z raportem Metody wyszukiwania...

Wdrożenie modułu płatności eservice dla systemu Virtuemart 2.0.x

System Informatyczny CELAB. Przygotowanie programu do pracy - Ewidencja Czasu Pracy

Instrukcja instalacji oraz wykorzystania podpisu cyfrowego

raceboard-s Szybki start

Logowanie do mobilnego systemu CUI i autoryzacja kodami SMS

1. Kolejki komunikatów POSIX

Tomasz Greszata - Koszalin

Instrukcja instalacji programu Plantator oraz transferu pliku danych z/do PC kolektor danych PT-20

Budowa systemów komputerowych

Kolejki komunikatów POSIX

Konfiguracja programu Outlook 2007 do pracy z nowym serwerem poczty (Exchange)

REJESTRATOR RES800 INSTRUKCJA OBSŁUGI

Logowanie do systemu Faktura elektroniczna

SIECI KOMPUTEROWE I BAZY DANYCH

Harmonogramowanie projektów Zarządzanie czasem

TESTER LX 9024 (SYSTEM ALARMOWY IMPULSOWY) INSTRUKCJA OBSŁUGI

System zarządzania bazą danych (SZBD) Proces przechodzenia od świata rzeczywistego do jego informacyjnej reprezentacji w komputerze nazywać będziemy

Politechnika Warszawska Wydział Matematyki i Nauk Informacyjnych ul. Koszykowa 75, Warszawa

Pierwsze kroki. Krok 1. Uzupełnienie danych własnej firmy

eć dzielona standardu POSIX

CRUSB Spartan KONWERTER CAN / USB

Microsoft Management Console

Instrukcja obsługi Norton Commander (NC) wersja 4.0. Autor: mgr inż. Tomasz Staniszewski

Spis zawartości Lp. Str. Zastosowanie Budowa wzmacniacza RS485 Dane techniczne Schemat elektryczny

SSK - Techniki Internetowe

Sieć komputerowa grupa komputerów lub innych urządzeo połączonych ze sobą w celu wymiany danych lub współdzielenia różnych zasobów, na przykład:

API transakcyjne BitMarket.pl

Kopia zapasowa i odzyskiwanie Podręcznik użytkownika

Wniosek o ustalenie warunków zabudowy

Rozdział 6. Pakowanie plecaka. 6.1 Postawienie problemu

GEO-SYSTEM Sp. z o.o. GEO-RCiWN Rejestr Cen i Wartości Nieruchomości Podręcznik dla uŝytkowników modułu wyszukiwania danych Warszawa 2007

Shared memory and messages. Functions. process 0. process 1. program 0. program 0. data 0. data 1. program 1. data 0. data 1.

Temat: Funkcje. Własności ogólne. A n n a R a j f u r a, M a t e m a t y k a s e m e s t r 1, W S Z i M w S o c h a c z e w i e 1

Przewodnik AirPrint. Ten dokument obowiązuje dla modeli atramentowych. Wersja A POL

Opis programu do wizualizacji algorytmów z zakresu arytmetyki komputerowej

Instrukcja obsługi zamka. bibi-z50. (zamek autonomiczny z czytnikiem identyfikatora Mifare)

Urządzenia do bezprzerwowego zasilania UPS CES GX RACK. 10 kva. Wersja U/CES_GXR_10.0/J/v01. Praca równoległa

System kontroli wersji SVN

Rejestr Windows - cz. II

Ostatnia cena sprzeda y klienta 1.0 dodatek do Symfonia Faktura dla 1 firmy

Instrukcja dotycząca generowania klucza dostępowego do Sidoma v8

Instrukcja zapisu do grup

Spis treści. Rozdział 1 ewyniki. mmedica - INSTR UKC JA UŻYTKO W NIKA

I. Zakładanie nowego konta użytkownika.

InsERT GT Własne COM 1.0

Strategia rozwoju kariery zawodowej - Twój scenariusz (program nagrania).

Śrubka zamykająca Uchwyt ścienny Przycisk kontrolny Lampka kontrolna

Wartości domyślne, szablony funkcji i klas

INFORMATOR TECHNICZNY WONDERWARE

0.1 Hierarchia klas Diagram Krótkie wyjaśnienie

Rozwiązywanie nazw w sieci. Identyfikowanie komputerów w sieci

Laboratorium z systemów operacyjnych. System plików - funkcje systemowe. Anna Wojak

Instrukcja użytkowania DRIVER. Programator z przewodem sterowniczym. DRIVER 610 lub lub 2 strefy DRIVER

Wtedy wystarczy wybrać właściwego Taga z listy.

Procesy. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 9 października 2011

Tablice, procesy, sygnały i nie tylko. Kurs systemu Unix 1

SUMA KONTROLNA (icmp_cksum) NUMER KOLEJNY (icmp_seq)

Instrukcja programu PControl Powiadowmienia.

Parowanie urządzeń Bluetooth. Instrukcja obsługi

Instalacja Plugin. Rys. 1. Folder Plugin.

elektroniczna Platforma Usług Administracji Publicznej

POMOC PSYCHOLOGICZNO-PEDAGOGICZNA Z OPERONEM. Vademecum doradztwa edukacyjno-zawodowego. Akademia

Mechanizmy z grupy IPC

Pracownia internetowa w każdej szkole. Opiekun pracowni internetowej SBS 2003 PING

Automatyczne generowanie transakcji do WB 1.0 dodatek do Finanse i Ksi gowo ERP dla 1 firmy

4.2 Sposób korzystania z l acza

Instrukcja zarządzania systemem informatycznym służącym do przetwarzania danych osobowych

ASD - ćwiczenia III. Dowodzenie poprawności programów iteracyjnych. Nieformalnie o poprawności programów:

1. Utwórz blok pamięci współdzielonej korzystając z poniższego kodu:

Temat zajęć: Obsługa systemu plików.

2010 W. W. Norton & Company, Inc. Nadwyżka Konsumenta

Instrukcja procesu aktywacji oraz obsługi systemu Banku Internetowego dla BS Mikołajki

Oprogramowanie klawiatury matrycowej i alfanumerycznego wyświetlacza LCD

13. Kolejki komunikatów POSIX

Surowiec Zużycie surowca Zapas A B C D S 1 0,5 0,4 0,4 0, S 2 0,4 0,2 0 0, Ceny x

Symfonia Produkcja Instrukcja instalacji. Wersja 2013

Transkrypt:

J. Ułasiewicz Programowanie aplikacji współbieżnych 1 9. Komunikacja przez pamięć dzieloną Metoda komunikacji przez wspólną pamięć może być użyta gdy procesy wykonywane są na maszynie jednoprocesorowej lub wieloprocesorowej ze wspólną pamięcią. Procesy Procesy mają rozdzielone segmenty danych - modyfikacje wykonane na danych w jednym procesie w żaden sposób nie przenoszą się do procesu drugiego. Aby procesy mogły mieć wspólny dostęp do tych samych danych należy: 1. Utworzyć oddzielny segment pamięci. 2. Udostępnić dostęp do segmentu zainteresowanym procesom. Prywatny P2 Segment danych procesu P1 Proces 1 Wspólny Proces 2 Segment danych procesu P1 Prywatny P1 Segment pamięci dzielonej Rys. 1 Procesy P1 i P2 komunikuję się poprzez wspólny obszar pamięci Wątki Wątki z natury dzielą obszar danych. Zmienne zadeklarowane jako zmienne globalne będą dostępne dla wątków. Komunikacja poprzez pamięć dzieloną Gdy procesy komunikują się przez wspólną pamięć, należy zadbać o zachowania spójności danych zawartych w dzielonym obszarze pamięci.

J. Ułasiewicz Programowanie aplikacji współbieżnych 2 9.1 Funkcje operujące na wspólnej pamięci standard Posix Standard Posix 1003.4 - funkcje pozwalające na tworzenie i udostępnianie segmentów pamięci: Działanie Utworzenie wspólnego segmentu pamięci Ustalenie rozmiaru segmentu Ustalenie odwzorowanie segmentu Cofnięcie odwzorowania segmentu Zmiana trybu dostępu Skasowanie segmentu pamięci Funkcja shm_open() ftruncate() map() munmap() mprotect() shm_unlink() Tabela 9-1 Funkcje POSIX operujące na pamięci wspólnej Tworzenie segmentu pamięci Tworzenie segmentu pamięci podobne jest do tworzenia pliku segment jest plikiem specjalnym. int shm_open(char *name, int oflag, mode_t mode ) name oflag mode Nazwa segmentu pamięci Flaga specyfikująca tryb utworzenia (jak dla plików), np. O_RDONLY, O_RDWR, O_CREAT Specyfikacja trybu dostępu (jak dla plików). Gdy funkcja zwraca liczbę nieujemną jest to uchwyt identyfikujący segment w procesie. Segment widziany jest jako plik specjalny w katalogu /dev/shmem. Ustalanie rozmiaru segmentu pamięci off_t ltrunc(int fdes, off_t offset, int whence) fdes offset whence Uchwyt segmentu zwracany przez poprzednią funkcję shm_open. Wielkość segmentu w bajtach. W tym przypadku stała SEEK_SET Funkcja zwraca wielkość segmentu lub 1 gdy błąd.

J. Ułasiewicz Programowanie aplikacji współbieżnych 3 Odwzorowanie segmentu pamięci wspólnej w obszar procesu, void *mmap(void * addr, size_t len, int prot, int flags, int fdes, off_t off) addr len prot flags fdes off Zmienna wskaźnikowa w procesie której wartość będzie przez funkcję zainicjowana. Może być 0. Wielkość odwzorowywanego obszaru. Specyfikacja dostępu do obszaru opisana w <sys/mman.h>. Może być PROT_READ PROT_WRITE Specyfikacja użycia segmentu, np. MAP_SHARED. Uchwyt segmentu wspólnej pamięci. Początek obszaru we wspólnej pamięci (musi to być wielokrotność strony 4K) Funkcja zwraca adres odwzorowanego obszaru lub 1 gdy błąd. addr 0 Segment danych procesu P1 Segment pamięci dzielonej len Odłączenie się od segmentu pamięci shm_unlink(char *name) name Nazwa segmentu pamięci. Każde wywołanie tej funkcji zmniejsza licznik udostępnień segmentu. Gdy osiągnie on wartość 0 czyli segment nie jest używany już przez żaden proces, segment jest kasowany. Schemat utworzenia i udostępnienia segmentu podano na poniższym rysunku.

J. Ułasiewicz Programowanie aplikacji współbieżnych 4 Deklaracja zmiennej wskaźnikowej buf Nazwa segmentu - "Bufor" Utworzenie segmentu fd = shm_open("bufor",...) Ustalenie wielkości segmentu ltrunc(...,fd,...) Odwzorowanie segmentu fd w przestrzeń adresową procesu buf = (char*) mmap(...,fd,...) Zapis / odczyt bufora buf Schemat użycia segmentu pamięci dzielonej Odączenie się od segmentu shm_unlink("bufor") Sposób wykorzystania wspólnej pamięci do komunikacji pomiędzy procesami. Proces macierzysty P1: 1. Deklaruje zmienną wskaźnikową buf. 2. Tworzy segment pamięci o nazwie Bufor - funkcja shm_open. 3. Ustala jego wielkość na B_SIZE - funkcją ltrunc. 4. Udostępnia segment w przestrzeni adresowej inicjując zmienną buf funkcja mmap. 5. Tworzy proces potomny P2 funkcja fork. 6. Czyta znaki z bufora buf. 7. Odłącza się od segmentu funkcja shm_unlink. Proces potomny P2: 1. Korzysta z utworzonego, udostępnionego i odwzorowanego jako buf segmentu pamięci. 2. Pisze znaki do bufora buf.

J. Ułasiewicz Programowanie aplikacji współbieżnych 5 #include <sys/mman.h> #define B_SIZE 60 // Rozmiar bufora #define STEPS 6 // Liczba krokow main(int argc,char *argv[]) { int i,stat; char *buf; char *tbuf; char name[16]; char c; int fd; // Deskryptor segmentu strcpy(name,"bufor"); // Allokacja pamieci dzielonej na bufor ------------- // Utworzenie segmentu pamieci --------------------- if((fd=shm_open(name,o_rdwr O_CREAT,0664))==-1)exit(-1) // Okreslenie rozmiaru obszaru pamieci --------------- if(ltrunc(fd, B_SIZE, SEEK_SET)!= B_SIZE) exit(-1); // Odwzorowanie segmentu fd w obszar pamieci procesow buf = (char *)mmap(0,b_size, PROT_READ PROT_WRITE, MAP_SHARED, fd, 0); if(buf == NULL) exit(-1); // Proces potomny P2 - pisze do pamieci wspolnej ----- if(fork() == 0) { for(i=0;i<steps;i++) { tbuf = buf; for(k=0;k<b_size;k++) { // Zapis do bufora *(tbuf++) = '0'+ (i%10); exit(0); else { // Proces macierzysty P1 czyta z pamięci wspólnej - for(i=0;i<steps;i++) { tbuf = buf; for(k=0;k<b_size;k++) { c = *(tbuf++); putch(c); pid = wait(&stat); // Zwolnienie nazwy ----- shm_unlink(name); return 0; Przykład 1 Procesy P1 i P2 komunikują się przez wspólny obszar pamięci

J. Ułasiewicz Programowanie aplikacji współbieżnych 6 9.2 Funkcje operujące na wspólnej pamięci IPC UNIX System V Klucze mechanizmów IPC Mechanizmy komunikacji międzyprocesowej (kolejki komunikatów, semafory, segmenty pamięci dzielonej) wymagają identyfikacji tych obiektów w obrębie pojedynczego komputera. Identyfikacja ta odbywa się za pomocą kluczy (ang. key). Do otrzymywania unikalnych kluczy generowanych na podstawie ścieżki do pliku służy funkcja ftok. key_t ftok(char *path, int id); Gdzie: path Id Scieżka do pliku Numer identyfikacyjny Funkcja zwraca klucz zależny od parametrów path, id. Tworzenie segmentu wspólnej pamięci Jeżeli mamy korzystać z segmentu pamięci wspólnej należy go najpierw utworzyć. Segment tworzy się przy pomocy funkcji shmget. int shmget(key_t key, size_t size, int flags) Key Size Flags Klucz identyfikujący semafor Minimalny rozmiar obszaru wspólnego Flagi specyfikujące tryb tworzenia i prawa dostępu (IP_CREAT, IPC_EXCL, SHM_RND, SHM_RDONLY) Funkcja zwraca: > 0 identyfikator segmentu wspólnego -1 błąd

J. Ułasiewicz Programowanie aplikacji współbieżnych 7 Dołączenie segmentu pamięci Po utworzeniu segment pamięci wspólnej musi być udostępniony w przestrzeni adresowej procesu który ma go używać. Udostępnienie to następuje przez wykonanie funkcji shmat. void *shmat(int id, void addr, int flags) Gdzie: Id addr flags identyfikator segmentu zwracany przez funkcję shmget Zmienna specyfikująca adres obszaru wspólnego Flagi specyfikujące tryb dostępu i przydzielania adresu Funkcja zwraca: > 0 - adres przydzielonego segmentu wspólnego -1 - błąd Gdy wartość zmiennej addr jest równa NULL system sam nada wartość adresowi po którym widziany jest dołączany segment pamięci. Gdy nie jest równy zeru działanie funkcji zależy od ustawienia flag. Gdy flaga SHM_RND jest ustawiona system przyjmie adres pod którym ma być widziany segment wspólny jako addr ale zaokrągli go do najbliższej strony. Gdy flaga SHM_RND jest wyzerowana system ustali adres pod którym ma być widziany segment wspólny jako dokładna wartość addr. Inną flagą mającą tu zastosowanie jest flaga SHM_RDONLY. Gdy jest ona ustawiona segment wspólny nadaje się tylko do odczytu. addr 0 Segment danych procesu P1 Segment pamięci dzielonej Rys. 2 Odwzorowanie segmentu pamięci dzielonej w przestrzeni adresowej procesu

J. Ułasiewicz Programowanie aplikacji współbieżnych 8 Dołączony za pomocą funkcji shmat segment pamięci wspólnej można odłączyć używając funkcji shmdt. int shmdt(void *addr) Parametr addr jest wartością zwróconą przez funkcję shmat. Funkcja shmdt zwraca 0 gdy wykona się poprawnie a 1 w gdy wystąpi błąd.

J. Ułasiewicz Programowanie aplikacji współbieżnych 9 #include <stdio.h> #include <unistd.h> #include <sys/shm.h> #define SIZE 8 main(int argc, char *argv[]) { int d, i; int *x; d = shmget(ftok(argv[0], 1), sizeof(int) * SIZE, IPC_CREAT 0600); x = shmat(d, NULL, 0); for (;;) { for (i = 0; i < SIZE; i++) printf("%3d ", x[i]); printf("\n"); for(i=0; i < SIZE;i++) x[i]++; sleep(1); 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 Przykład 2 Wykonanie pojedynczej kopii programu shmem1 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 4 Przykład 3 Wykonanie dwóch kopii programu shmem1

J. Ułasiewicz Programowanie aplikacji współbieżnych 10 // Producent konsument (rozwiązanie bledne) #include <stdio.h> #include <unistd.h> #include <sys/shm.h> #define TSIZE 64 typedef struct { int licznik; char tekst[tsize]; buft; main(int argc, char *argv[]) { int d, i; buft *buf; d = shmget(ftok(argv[0], 1), sizeof(buft), IPC_CREAT 0600); buf = shmat(d, NULL, 0); if(argc < 2) { printf("uzycie shmpk [P K]\n"); exit(0); if(argv[1][0] == 'P') { // Producent printf("producent\n"); for (;;) { while(buf->licznik > 0); // wait sprintf(buf->tekst,"producent krok %d ",i); buf->licznik++; i++; sleep(1); if(argv[1][0] == 'K') { // Konsument printf("konsument\n"); for (;;) { while(buf->licznik == 0); // wait printf("%s\n",buf->tekst); buf->licznik--; sleep(1); memset(buf,0,sizeof(buft)); printf("uzycie shmpk [P K]\n"); Przykład 4 Problem producenta / konsumenta (rozw. nieprawidłowe)

J. Ułasiewicz Programowanie aplikacji współbieżnych 11 9.3 Rozwiązanie problemu producenta i konsumenta semafory nienazwane Producenci buf[bsize] Konsumenci P1 BSIZE-1 K1 P2 Pk full head x x x 3 2 1 0 empty tail K2 Km cnt mutex segment pamieci dzielonej #include <sys/mman.h> #include <fcntl.h> #include <semaphore.h> #define BSIZE 4 // Rozmiar bufora #define LSIZE 80 // Dlugosc linii typedef struct { char buf[bsize][lsize]; int head; int tail; int cnt; sem_t mutex; sem_t empty; sem_t full; bufor_t; main(int argc,char *argv[]) { int i,stat,k, pid, size, fd,res; bufor_t *wbuf ; char c; // Utworzenie segmentu --------------------------- shm_unlink("bufor"); if((fd=shm_open("bufor", O_RDWR O_CREAT, 0774)) == -1){ perror("open"); exit(-1); printf("fd: %d\n",fd); size = ftruncate(fd, BSIZE); if(size < 0) {perror("trunc"); exit(-1);

J. Ułasiewicz Programowanie aplikacji współbieżnych 12 // Odwzorowanie segmentu fd w obszar pamieci procesow wbuf = (bufor_t *)mmap(0,bsize,prot_read PROT_WRITE, MAP_SHARED, fd, 0); if(wbuf == NULL) {perror("map"); exit(-1); // Inicjacja obszaru -------------------------------- wbuf-> cnt = 0; wbuf->head = 0; wbuf->tail = 0; if(sem_init(&(wbuf->mutex),1,1)){ perror("mutex");exit(0); if(sem_init(&(wbuf->empty),1,bsize)) { perror("empty"); exit(0); if(sem_init(&(wbuf->full),1,0)) { perror("full"); exit(0); // Tworzenie procesow ------------- if(fork() == 0) { // Producent for(i=0;i<10;i++) { // printf("producent: %i\n",i); printf("producent - cnt:%d head: %d tail: %d\n", wbuf-> cnt,wbuf->head,wbuf->tail); sem_wait(&(wbuf->empty)); sem_wait(&(wbuf->mutex)); sprintf(wbuf->buf[wbuf->head],"komunikat %d",i); wbuf-> cnt ++; wbuf->head = (wbuf->head +1) % BSIZE; sem_post(&(wbuf->mutex)); sem_post(&(wbuf->full)); sleep(1); shm_unlink("bufor"); exit(i); // Konsument ------------------ for(i=0;i<10;i++) { printf("konsument - cnt: %d odebrano %s\n",wbuf->cnt,wbuf->buf[wbuf->tail]); sem_wait(&(wbuf->full)); sem_wait(&(wbuf->mutex)); wbuf-> cnt --; wbuf->tail = (wbuf->tail +1) % BSIZE; sem_post(&(wbuf->mutex)); sem_post(&(wbuf->empty)); sleep(1);

J. Ułasiewicz Programowanie aplikacji współbieżnych 13 pid = wait(&stat); shm_unlink("bufor"); sem_close(&(wbuf->mutex)); sem_close(&(wbuf->empty)); sem_close(&(wbuf->full)); return 0; Przykład 9-5 Rozwiązanie problemu producenta i konsumenta za pomocą semaforów nienazwanych

J. Ułasiewicz Programowanie aplikacji współbieżnych 14 9.4 Rozwiązanie problemu producenta i konsumenta semafory nazwane Producenci P1 buf[bsize] BSIZE-1 Konsumenci K1 P2 Pk head x x x 3 2 1 0 tail K2 Km cnt segment pamieci dzielonej full mutex empty #include <sys/mman.h> #include <fcntl.h> #include <semaphore.h> #define BSIZE 4 // Rozmiar bufora #define LSIZE 80 // Dlugosc linii typedef struct { // Obszar wspólny char buf[bsize][lsize]; int head; int tail; int cnt; bufor_t; main(int argc,char *argv[]) { int i,stat,k, pid, size, fd,res; bufor_t *wbuf ; char c; sem_t *mutex; sem_t *empty; sem_t *full; // Utworzenie segmentu --------------------------- shm_unlink("bufor"); if((fd=shm_open("bufor", O_RDWR O_CREAT, 0774)) == -1){ perror("open"); exit(-1); printf("fd: %d\n",fd);

J. Ułasiewicz Programowanie aplikacji współbieżnych 15 size = ftruncate(fd, BSIZE); if(size < 0) {perror("trunc"); exit(-1); // Odwzorowanie segmentu fd w obszar pamieci procesow wbuf = ( bufor_t *)mmap(0,bsize, PROT_READ PROT_WRITE, MAP_SHARED, fd, 0); if(wbuf == NULL) {perror("map"); exit(-1); // Inicjacja obszaru -------------------------------- wbuf-> cnt = 0; wbuf->head = 0; wbuf->tail = 0; // Utworzenie semaforw ------------------------- mutex = sem_open("mutex",o_creat,s_irwxu,1); empty = sem_open("empty",o_creat,s_irwxu,bsize); full = sem_open("full",o_creat,s_irwxu,0); // Utworzenie procesow ------------------------- if(fork() == 0) { // Producent for(i=0;i<10;i++) { // printf("producent: %i\n",i); sem_wait(empty); sem_wait(mutex); printf("producent - cnt:%d head: %d tail: %d\n", wbuf-> cnt,wbuf->head,wbuf->tail); sprintf(wbuf->buf[wbuf->head],"komunikat %d",i); wbuf-> cnt ++; wbuf->head = (wbuf->head +1) % BSIZE; sem_post(mutex); sem_post(full); sleep(1); shm_unlink("bufor"); exit(i);

J. Ułasiewicz Programowanie aplikacji współbieżnych 16 // Konsument ------------------ for(i=0;i<10;i++) { sem_wait(full); sem_wait(mutex); printf("konsument - cnt: %d odebrano %s\n", wbuf->cnt,wbuf->buf[wbuf->tail]); wbuf-> cnt --; wbuf->tail = (wbuf->tail +1) % BSIZE; sem_post(mutex); sem_post(empty); sleep(1); pid = wait(&stat); shm_unlink("bufor"); sem_close(mutex); sem_close(empty); sem_close(full); sem_unlink("mutex"); sem_unlink("empty"); sem_unlink("full"); return 0; Przykład 9-6 Rozwiązanie problemu producenta i konsumenta za pomocą semaforów nazwanych