Sylwia Grochowska, Katarzyna Humienna
Sprawozdanie z projektu nr 2 - „Problem czytelnika i pisarza”
0. W
stęp
Zadanie zostało zrealizowane w trzech trybach – faworyzowanie pisarza, faworyzowanie czytelnika oraz traktowanie obu „osób” w taki sam sposób. Każdy tryb stanowi osobną aplikację, którą kompilujemy w trybie O3
dołączywszy biblioteki lpthread. Programy zrealizowano na zmiennych mutex. Poniżej omówienie poszczególnych programów, które poprzedzę kilkoma zasadami korzystania:
•
przy uruchamianiu pliku wyjściowego należy podać dwa parametry, które oznaczają kolejno: maksymalną liczbę czytelników w bibliotece oraz maksymalną liczbę pisarzy
•
czas, który osoba spędza w czytelni (dla pisarzy pisalni) i poza biblioteką jest losowany.
•
Tworzymy wątki: czytelnia, rejestracja dwa, jeden odnoszący się do czytelnika, drugi odnoszący się do pisarza wykładowcy. Mamy też dwie ważne funkcje: fczytelnik oraz fpisarz, które obsługują mutexy dotyczące czytelnika oraz dotyczące pisarza. Za każdym razem zachowują się inaczej.
1. O
pcja dopuszczająca zagłodzenie czytelników
W ramach rządowego programu „ Młodziesz pisze dla młodzierzy ” otworzono specjalną czytelnię. Zgłoszeni uprzednio wolontariusze otrzymują identyfikatory. Po okazaniu go w rejestracji wchodzą do specjalnego pokoju, gdzie mają napisać nie za długie opowiadanie. Czekająca w poczekalni grupa będzie mogła je potem przeczytać, chyba, że przyjdzie następny wolontariusz. Wiadomo, że chodzi o jak największą wydajność pisaniny, bo im więcej opowiadań się stworzy, tym więcej unijnej dotacji dostanie następna edycja programu. Dlatego wolontariusze mają odgórny nakaz wpuszczania innych wolontariuszy w kolejkę. Po nich zaś dopiero wejdzie grupa czytelników, z których jeden będzie czytał opowiadanie, a reszta dogłębnie je analizowała i dyskutowała.
Void fczytelnik(void *number) Parametr przekazany w pętli zewnętrznej w funkcji main, jako liczba reprezentująca każdego czytelnika oraz pisarza
W nieskończonej pętli powtarza czynności:
•
czytelnik wchodzi do poczekalni (blokujemy wątek czytelnika w
poczekalni
•
sprawdza wątek rejestracji: najpierw, czy nie ma pisarza, a potem, czy nie ma nikogo
•
jeżeli jest czytelnik lub czytelnia, to wchodzi razem z kolegami
•
losuje czas, który spędzi w czytelni
•
czytelnicy wychodzą
•
każdy losuje czas do następnych odwiedzin
Void fpisarz(void *number)
Parametr przekazany w pętli zewnętrznej w funkcji main, jako liczba reprezentująca każdego czytelnika oraz pisarza
W nieskończonej pętli powtarza czynności:
•
pisarz wchodzi do poczekalni
•
sprawdza w rejestracji, czy czytelnia jest pusta
•
losuje czas, który spędzi w czytelni
•
wychodzi i sprawdza, czy w poczekalni nie ma pisarza: jeżeli jest, to go wpuszcza, jeżeli nie ma, zostawia drzwi otwarte
•
losuje czas do następnych odwiedzin
Przy każdej zmianie dokonanej w kolejce blokują się wątki, których ta zmiana dotyczy 2. O
pcja faworyzująca czytelników
W tym momencie sytuacja się odwraca: Za sprawą kawki i czekoladowych pianek, które nieoczekiwanie pojawiły się na ladzie pani w rejestracji, ta przymyka oko na niektóre szemrane interesy czytelników. Po znajomości rozbursmaniona młodzież wchodzi kolejnymi grupami i wpycha się w kolejkę.
Void fczytelnik(void *number) Parametr przekazany w pętli zewnętrznej w funkcji main, jako liczba reprezentująca każdego czytelnika oraz pisarza
W nieskończonej pętli powtarza czynności:
•
czytelnik wchodzi do poczekalni (blokujemy wątek czytelnika w
poczekalni
•
sprawdza wątek rejestracji: najpierw, czy nie ma pisarza, a potem, czy
•
jeżeli czytelnia jest pusta, to wchodzi z kolegami
•
losuje czas, który spędzi w czytelni
•
czytelnicy wychodzą i sprawdzają, czy nie czeka na nich kolejna
grupa
•
każdy losuje czas do następnych odwiedzin
Void fpisarz(void *number)
Parametr przekazany w pętli zewnętrznej w funkcji main, jako liczba reprezentująca każdego czytelnika oraz pisarza
W nieskończonej pętli powtarza czynności:
•
pisarz wchodzi do poczekalni
•
sprawdza w rejestracji, czy czytelnia jest pusta
•
losuje czas, który spędzi w czytelni
•
wychodzi
•
losuje czas do następnych odwiedzin
3. O
pcja nie faworyzująca nikogo
Pani w rejestracji zdenerwowała się nie na żarty. „Co za rejwach! Co za galimatias! Nie będzie żadnych priorytetów, więc nie będzie także poszkodowanych! Ustawiać mi się w kolejeczkę, wszyscy są równi!” krzyknęła.
„Proszę pani...” odezwał się chuderlawy chłopaczek, który do tej pory miał wielką zabawę z całej sytuacji „jest nas tak dużo. Jeżeli będziemy wchodzić pojedynczo” przełknął głośno ślinę „to ja się tam nigdy nie dostanę...” na końcu zdania głos mu zadrżał, a twarz się nieco wydłużyła. Rejestratorka zmierzyła go wzrokiem. Żal się jej zrobiło tego chłopaka, wyglądało na to, że niewiele miał w życiu uciechy. „W porządku” oznajmiła. „Możecie wchodzić grupami”.
Blondynek rozpromienił się.
W tym wypadku należy użyć zmiennych pomocniczych – warunkowych. Służą one do informowania kolejki, co się dzieje z czytelnią.
Void fczytelnik(void *number) Parametr przekazany w pętli zewnętrznej w funkcji main, jako liczba reprezentująca każdego czytelnika oraz pisarza
W nieskończonej pętli powtarza czynności:
•
czytelnik wchodzi do poczekalni i ustawia się w kolejkę
•
sprawdza wątek rejestracji, czy czytelnia jest może pusta
•
dopóki nie jest na czele kolejki, to nie wejdzie, czeka
•
kiedy jest pierwszy, wchodzi
•
kolejka się przesuwa do przodu
•
czytelnicy w poczekalni wchodzą
•
ogłasza się, że czytelnicy są w czytelni (przepuszcza innych
czytelników)
•
losuje się czas dla czytelników
•
wychodzą, drzwi otwarte
•
ogłasza się pisarzom, że czytelnicy wyszli
•
czytelnicy losują czas do następnego wejścia
Void fpisarz(void *number)
Parametr przekazany w pętli zewnętrznej w funkcji main, jako liczba reprezentująca każdego czytelnika oraz pisarza
W nieskończonej pętli powtarza czynności:
•
pisarz wchodzi do poczekalni i ustawia się w kolejkę
•
sprawdza wątek rejestracji, czy czytelnia jest może pusta
•
dopóki nie jest na czele kolejki, to nie wejdzie, czeka
•
kiedy jest pierwszy, wchodzi
•
kolejka się przesuwa do przodu
•
ogłasza się, że pisarz jest w czytelni
•
losuje się czas dla pisarza
•
wychodzi, drzwi otwarte
•
ogłasza się wszystkim, że pisarz wyszedł
•
pisarz losuje czas do następnego ustawienia się do kolejki
#include <stdio.h>
sleep((rand()%10)+1);
czytelnikow
#include <stdlib.h>
}
#include <pthread.h>
czytelnia_pisarze--;
pthread_mutex_unlock(&poczekalnia_czytelnik);
wypisz(czytelnicy_poczekalnia,
czytelnia_czytelnicy++; //zwiekszam ilosc czytelnikow w czytelni
//dopuszczamy opcję zagłodzenia
pisarze_poczekalnia, czytelnia_czytelnicy, czytelnia_pisarze);
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
if(pisarze_poczekalnia == 0){
czytelnia_czytelnicy, czytelnia_pisarze);
czytelników
}
pthread_mutex_unlock(&rejstracja_pisarz); //Żaden pisarz po pthread_mutex_unlock(&rejstracja_czytelnik); pthread_mutex_t czytelnia;
mnie nie wchodzi, włazi plebs
pthread_mutex_t rejstracja_czytelnik;
}
sleep((rand()%10)+1); //Losuje ile czasu zabawi w czytelni
pthread_mutex_t rejstracja_pisarz;
pthread_mutex_unlock(&czytelnia); //zwalnia czytelnie
pthread_mutex_t poczekalnia_czytelnik;
sleep((rand()%15)+1); //Losuje czas do nastepnych odwiedzin w czytelni pthread_mutex_lock(&rejstracja_czytelnik);{ //probuje sie pthread_mutex_t poczekalnia_pisarz;
}
'wyrejestrowac', zajmuje 'rejestracje' by nie pomylic numeru z innym int czytelnia_pisarze;
return NULL;
(zapobiega wyscigom)
int czytelnia_czytelnicy;
}
czytelnia_czytelnicy--; //zmniejszam ilosc
int czytelnicy_poczekalnia;
czytelnikow w czytelni
int pisarze_poczekalnia;
int main(int argc, char *argv[]){
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
int ilosc_czytelnikow;
czytelnia_czytelnicy, czytelnia_pisarze);
void intro(){
int ilosc_pisarzy;
if(czytelnia_czytelnicy == 0){
printf(" _____ ^\n");
int sys_ret;
pthread_mutex_unlock(&czytelnia); //jezeli czytelnik wychodzi printf(" | | (o)\n");
int i;
jako ostatni, zwalnia czytelnie
printf(" __|______|__ -|-\n");
srand(time(NULL));
}
printf(" ___(___________(_ |i ||\n");
}
printf(" / / |* ||\n");
if(argc < 3){
pthread_mutex_unlock(&rejstracja_czytelnik);
printf(" \________________\__ | i|\n");
printf("Zbyt malo parametrow");
sleep((rand()%15)+1); //Losuje czas do nastepnych odwiedzin w czytelni printf(" [_________________| *-.-*\n");
return -1;
}
printf(" C Z Y T E L N I A\n");
}
else{
return NULL;
pause();
ilosc_czytelnikow = atoi(argv[1]);
}
ilosc_pisarzy = atoi(argv[2]);
}
}
void* fpisarz(void *number){
int i;
void wypisz(int rq, int wq, int ri, int wi){
while(1){
int sys_ret;
intro();
pthread_mutex_lock(&poczekalnia_pisarz);{ //pisarz próbuje się sys_ret = system("clear");
zarejestrować
printf("Pisarzy w kolejce: %d\n Czytelników w kolejce: %d\n czytelnia_czytelnicy = 0; pisarze_poczekalnia++; //zmniejszam ilosc oczekujacych pisarzy
Stan czytelni: %d pisarzy %d czytelników \n", wq, wr, ri, wi); czytelnicy_poczekalnia = 0;
czytelnia_pisarze = 0;
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
}
pisarze_poczekalnia = 0;
czytelnia_czytelnicy, czytelnia_pisarze);
pthread_t * czytelnik;
}
void* fczytelnik(void *number){
czytelnik = (pthread_t*)malloc(ilosc_czytelnikow*sizeof(pthread_t)); pthread_mutex_unlock(&poczekalnia_pisarz);
int i;
pthread_t * pisarz;
pthread_mutex_lock(&czytelnia); //zajmuje czytelnie
while(1){
pisarz = (pthread_t*)malloc(ilosc_pisarzy*sizeof(pthread_t));
pthread_mutex_lock(&poczekalnia_pisarz);{
pthread_mutex_lock(&poczekalnia_czytelnik);{
pthread_mutex_init(&rejstracja_czytelnik, NULL);
pisarze_poczekalnia--;
czytelnicy_poczekalnia++; pthread_mutex_init(&rejstracja_pisarz, NULL);
}
//wieksza kolejka
pthread_mutex_init(&poczekalnia_czytelnik, NULL);
pthread_mutex_unlock(&poczekalnia_pisarz);
pthread_mutex_init(&poczekalnia_pisarz, NULL);
czytelnia_pisarze++; //zwiekszam ilosc pisarzy w czytelni
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
pthread_mutex_init(&czytelnia, NULL);
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia, czytelnia_czytelnicy, czytelnia_czytelnicy, czytelnia_pisarze);
for(i=1;i<=ilosc_czytelnikow;i++){
czytelnia_pisarze);
}
pthread_create(&czytelnik[i], NULL, fczytelnik, (void*)i);
}
sleep((rand()%15)+1);
pthread_mutex_unlock(&poczekalnia_czytelnik);
pthread_mutex_lock(&rejstracja_pisarz);
for(i=1;i<=ilosc_pisarzy;i++){
czytelnia_pisarze--;
{ //sprawdzam czy nie ma pisarza
pthread_create(&pisarz[i], NULL, fpisarz, (void*)i);
wypisz(czytelnicy_poczekalnia,
}
pisarze_poczekalnia, czytelnia_czytelnicy, czytelnia_pisarze);
pthread_mutex_lock(&rejstracja_czytelnik);{ //sprawdzam,
pthread_mutex_unlock(&czytelnia); //zwalnia czytelnie
czy nie ma nikogo
for(i=1;i<=ilosc_czytelnikow;i++){
sleep((rand()%20)+1);
if(czytelnia_czytelnicy == 0){
pthread_join(czytelnik[i], NULL);
}
}
pthread_mutex_lock(&czytelnia); //zajmuję czytelnię i o
return NULL;
//printf("czytelnia zajeta\n");
for(i=1;i<=ilosc_pisarzy;i++){
}
}
pthread_join(pisarz[i], NULL);
}
int main(int argc, char *argv[]){
pthread_mutex_lock(&poczekalnia_czytelnik);{
int ilu_czytelnikow;
return 0;
int ilu_pisarzy;
czytelnicy_poczekalnia--; //skoro ktos jest w czytelni, to jest }
int sys_ret;
mniej w kolejce (blokujemy dochodzenie kolejnych)
----------------------------------------------------------------------------------------------
int i;
}
#include <stdio.h>
srand(time(NULL));
#include <stdlib.h>
if(argc < 3){
pthread_mutex_unlock(&poczekalnia_czytelnik);
#include <pthread.h>
printf("Zbyt malo parametrow");
return -1;
czytelnia_czytelnicy++;
}
//zaglodzenie pisarzy
else{
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
pthread_mutex_t czytelnia;
ilu_czytelnikow = atoi(argv[1]);
czytelnia_czytelnicy, czytelnia_pisarze);
pthread_mutex_t rejstracja_czytelnik;
ilu_pisarzy = atoi(argv[2]);
}
pthread_mutex_t poczekalnia_czytelnik;
}
pthread_mutex_t poczekalnia_pisarz;
pthread_mutex_unlock(&rejstracja_czytelnik);
int czytelnia_pisarze;
}
int czytelnia_czytelnicy;
intro();
pthread_mutex_unlock(&rejstracja_pisarz); int czytelnicy_poczekalnia; int pisarze_poczekalnia;
czytelnia_czytelnicy = 0;
czytelnicy_poczekalnia = 0;
sleep((rand()%10)+1);
void intro(){
czytelnia_pisarze = 0;
printf(" _____ ^\n");
pisarze_poczekalnia = 0;
printf(" | | (o)\n");
pthread_t * czytelnik;
pthread_mutex_lock(&rejstracja_czytelnik);{ //rejestracja czytelnika, żeby printf(" __|______|__ -|-\n"); czytelnik = (pthread_t*)malloc(ilu_czytelnikow*sizeof(pthread_t)); nikt za niego nie wszedł
printf(" ___(___________(_ |i ||\n");
pthread_t * pisarz;
czytelnia_czytelnicy--;
printf(" / / |* ||\n");
pisarz = (pthread_t*)malloc(ilu_pisarzy*sizeof(pthread_t));
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
printf(" \________________\__ | i|\n");
pthread_mutex_init(&rejstracja_czytelnik, NULL);
czytelnia_czytelnicy, czytelnia_pisarze);
printf(" [_________________| *-.-*\n");
pthread_mutex_init(&poczekalnia_czytelnik, NULL);
if(czytelnia_czytelnicy == 0){
printf(" C Z Y T E L N I A\n");
pthread_mutex_init(&poczekalnia_pisarz, NULL);
pthread_mutex_unlock(&czytelnia); //drzwi zostawiam otwarte
pthread_mutex_init(&czytelnia, NULL);
}
pause();
}
for(i=1;i<=ilu_czytelnikow;i++){
pthread_mutex_unlock(&rejstracja_czytelnik);
}
pthread_create(&czytelnik[i], NULL, fczytelnik, (void*)i);
sleep((rand()%15)+1);
}
}
void wypisz(int rq, int wq, int ri, int wi){
return NULL;
int sys_ret;
for(i=1;i<=ilu_pisarzy;i++){
}
sys_ret = system("clear");
pthread_create(&pisarz[i], NULL, fpisarz, (void*)i);
printf("Czytelników w kolejce: %d\n Pisarzy w kolejce:
}
void* fpisarz(void *number){
%d\n Stan czytelni: %d czytelników %d pisarzy]", rq, wq, ri, wi); int i;
for(i=1;i<=ilu_czytelnikow;i++){
while(1){
}
pthread_join(czytelnik[i], NULL);
pthread_mutex_lock(&poczekalnia_pisarz);{
}
pisarze_poczekalnia++;
void* fczytelnik(void *number){
int i;
for(i=1;i<=ilu_pisarzy;i++){
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
while(1){
pthread_join(pisarz[i], NULL);
czytelnia_czytelnicy, czytelnia_pisarze);
pthread_mutex_lock(&poczekalnia_czytelnik);{
}
}
czytelnicy_poczekalnia++;
//zwiekszam ilosc oczekujacych czytelnikow
return 0;
pthread_mutex_unlock(&poczekalnia_pisarz);
}
if((czytelnia_pisarze == 0)&&(pisarze_poczekalnia < 2)) wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
----------------------------------------------------------------------------------------------
{ //jeżeli brak pisarzy w czytelni i poczekalni, można sprobowac
czytelnia_czytelnicy, czytelnia_pisarze);
#include <stdio.h>
}
#include <stdlib.h>
pthread_mutex_lock(&rejstracja_pisarz);
#include <pthread.h>
}
pthread_mutex_unlock(&poczekalnia_czytelnik);
pthread_mutex_lock(&poczekalnia_pisarz);{
pthread_mutex_lock(&rejstracja_czytelnik);{ //probuje wejsc do pisarze_poczekalnia--;
'rejestracji', zajmuje ja by nie pomylic numeru z innym (zapobiega wyscigom) //wszyscy sa zadowoleni
}
if(czytelnia_czytelnicy == 0){
pthread_mutex_t czytelnia;
pthread_mutex_unlock(&poczekalnia_pisarz);
pthread_mutex_lock(&czytelnia); //jezeli czytelnik wchodzi jako pthread_mutex_t poczekalnia_czytelnik;
czytelnia_pisarze++;
pierwszy, zajmuje czytelnie
pthread_mutex_t poczekalnia_pisarz;
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia, czytelnia_czytelnicy, }
pthread_mutex_t rejestracja;
czytelnia_pisarze);
pthread_mutex_lock(&poczekalnia_czytelnik);{
pthread_cond_t wart_warunkowa_czytelnikow;
czytelnicy_poczekalnia--; //zmniejszam ilosc oczekujacych
pthread_cond_t wart_warunkowa_pisarzy;
czytelni
int czytelnia_czytelnicy;
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
int czytelnicy_poczekalnia;
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
czytelnia_czytelnicy, czytelnia_pisarze);
int pisarze_poczekalnia;
czytelnia_czytelnicy, czytelnia_pisarze);
}
int * kolejka_czytelnikow;
}
pthread_mutex_unlock(&czytelnia); //oblokowanie czytelni
int * kolejka_pisarzy;
pthread_mutex_unlock(&rejestracja);
int * kolejka;
pthread_cond_broadcast(&wart_warunkowa_pisarzy); // Pusta
pthread_cond_broadcast(&wart_warunkowa_czytelnikow); czytelnia, nastepny proszszsz void intro(){
printf(" _____ ^\n");
sleep((rand()%10)+1);
pthread_cond_broadcast(&wart_warunkowa_czytelnikow);
printf(" | | (o)\n");
sleep((rand()%15)+1);
printf(" __|______|__ -|-\n");
pthread_mutex_lock(&rejestracja);{ //zbiea sie z czytelni
}
printf(" ___(___________(_ |i ||\n");
czytelnia_czytelnicy--; //zmniejszam ilosc czytelnikow w czytelni return NULL;
printf(" / / |* ||\n");
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
}
printf(" \________________\__ | i|\n");
czytelnia_czytelnicy, czytelnia_pisarze);
printf(" [_________________| *-.-*\n");
if(czytelnia_czytelnicy == int main(int argc, char *argv[]){
printf(" C Z Y T E L N I A\n");
0){
int ilu_czytelnikow;
pthread_mutex_unlock(&czytelnia); //jezeli czytelnik wychodzi jako int ilu_pisarzy; pause();
ostatni, zwalnia czytelnie
int sys_ret;
pthread_cond_broadcast(&wart_warunkowa_pisarzy); //Mowi
int i;
}
pisarzom zeby sprawdzili kolejke, bo wszyscy czytelnicy wyszli
srand(time(NULL));
}
void wypisz(int rq, int wq, int ri, int wi){
if(argc < 3){
int i;
}
printf("Zbyt malo parametrow");
int sys_ret;
pthread_mutex_unlock(&rejestracja);
return -1;
sys_ret = system("clear");
sleep((rand()%15)+1); //Losuje czas do nastepnych odwiedzin w czytelni }
}
else{
printf("Czytelników w kolejce: %d\n Pisarzy w kolejce:
return NULL;
ilu_czytelnikow = atoi(argv[1]);
%d\n Stan czytelni: %d czytelników %d pisarzy]", rq, wq, ri, wi);
}
ilu_pisarzy = atoi(argv[2]);
}
printf("\nKolejka:");
void* fpisarz(void *number){
for(i=0;i<rq+wq;i++)
int i;
printf(" %d ", kolejka[i]);
while(1){
intro();
pthread_mutex_lock(&poczekalnia_pisarz);{ //chce do rejestracji, ide do
}
kolejki
czytelnia_czytelnicy = 0;
czytelnicy_poczekalnia = 0;
kolejka[czytelnicy_poczekalnia+pisarze_poczekalnia] = -
czytelnia_pisarze = 0;
void* fczytelnik(void *number){
(int)number; //pisarzy oznaczamy liczbą ujemną, dla rozróżnienia
pisarze_poczekalnia = 0;
int i;
pisarze_poczekalnia++; pthread_t * czytelnik;
while(1){
//zmniejszam ilosc oczekujacych pisarzy
czytelnik = (pthread_t*)malloc(ilu_czytelnikow*sizeof(pthread_t)); pthread_mutex_lock(&poczekalnia_czytelnik);{
pthread_t * pisarz;
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
pisarz = (pthread_t*)malloc(ilu_pisarzy*sizeof(pthread_t));
kolejka[czytelnicy_poczekalnia+pisarze_poczekalnia] =
czytelnia_czytelnicy, czytelnia_pisarze);
kolejka_czytelnikow = (int*)malloc((ilu_czytelnikow+1)*sizeof(int)); (int)number; //Przychodzi czytelnik do czytelni
}
kolejka_pisarzy = (int*)malloc((ilu_pisarzy+1)*sizeof(int));
czytelnicy_poczekalnia++;
kolejka = (int*)malloc((ilu_czytelnikow+ilu_pisarzy+1)*sizeof(int)); pthread_mutex_unlock(&poczekalnia_pisarz);
pthread_mutex_init(&rejestracja, NULL);
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
pthread_mutex_lock(&rejestracja);{
pthread_mutex_init(&poczekalnia_czytelnik, NULL);
czytelnia_czytelnicy, czytelnia_pisarze);
while(kolejka[0]!=(-
pthread_mutex_init(&poczekalnia_pisarz, NULL);
}
(int)number)){
pthread_mutex_init(&czytelnia, NULL);
pthread_cond_init(&wart_warunkowa_czytelnikow, NULL);
pthread_mutex_unlock(&poczekalnia_czytelnik);
pthread_cond_wait(&wart_warunkowa_pisarzy,
pthread_cond_init(&wart_warunkowa_pisarzy, NULL);
pthread_mutex_lock(&rejestracja);{ //chce sie zarejestrowac
&rejestracja); //czekam na ogłoszenie
while(kolejka[0]!=(int)number){
}
kolejka_czytelnikow[0]=0;
}
for(i=1;i<=ilu_czytelnikow;i++){
pthread_cond_wait(&wart_warunkowa_czytelnikow,
pthread_mutex_unlock(&rejestracja);
pthread_create(&czytelnik[i], NULL, fczytelnik, (void*)i);
&rejestracja); //nie moge wejsc
pthread_mutex_lock(&czytelnia);{
kolejka_czytelnikow[i]=0;
}
czytelnia_pisarze++;
kolejka[i-1]=0;
if(czytelnia_czytelnicy == 0){
}
pthread_mutex_lock(&poczekalnia_pisarz);{
pthread_mutex_lock(&czytelnia); //jezeli czytelnik wchodzi
kolejka_pisarzy[0]=0;
jako pierwszy, zajmuje czytelnie
for(i=0;i<czytelnicy_poczekalnia+pisarze_poczekalnia;i++) for(i=1;i<=ilu_pisarzy;i++){
}
pthread_create(&pisarz[i], NULL, fpisarz, (void*)i);
kolejka[i]=kolejka[i+1]; //kolejka przesuwa kolejka_pisarzy[i]=0; pthread_mutex_lock(&poczekalnia_czytelnik);{
się do przodu
kolejka[i+ilu_czytelnikow-1]=0;
}
for(i=0;i<czytelnicy_poczekalnia+pisarze_poczekalnia;i++)
pisarze_poczekalnia--;
}
for(i=1;i<=ilu_czytelnikow;i++){
kolejka[i]=kolejka[i+1]; //przesuwam
pthread_join(czytelnik[i], NULL);
kolejke do przodu
pthread_mutex_unlock(&poczekalnia_pisarz);
}
czytelnicy_poczekalnia--; //jest nas mniej
wypisz(czytelnicy_poczekalnia, pisarze_poczekalnia,
for(i=1;i<=ilu_pisarzy;i++){
}
czytelnia_czytelnicy, czytelnia_pisarze);
pthread_join(pisarz[i], NULL);
}
pthread_mutex_unlock(&poczekalnia_czytelnik);
sleep((rand()%10)+1);
return 0;
czytelnia_czytelnicy++; //zwiekszam ilosc czytelnikow w
czytelnia_pisarze--;
}