/* * Przykładowy program dla kursu "POSIX Threads" z wikibooks.pl * * Temat: blokady zapis/odczy (rwlock) * * Autor: Wojciech Muła * Ostatnia zmiana: 2010-03-xx */
#define _POSIX_C_SOURCE 200809L#include<stdlib.h>#include<stdio.h>#include<pthread.h>#include<errno.h>#include<time.h>voidms_sleep(constunsignedms);#define test_errno(msg) do{if (errno) {perror(msg); exit(EXIT_FAILURE);}} while(0)pthread_rwlock_tblokada;intwartosc;// obiekt chroniony blokadą/* wątek zmienia wartość */void*pisarz(void*numer){while(1){printf(" pisarz #%d czeka na dostęp\n",(int)numer);errno=pthread_rwlock_wrlock(&blokada);test_errno("pthread_rwlock_wrlock");printf(" pisarz #%d ustawia nową wartość\n",(int)numer);ms_sleep(113);printf(" pisarz #%d zwalnia blokadę\n",(int)numer);errno=pthread_rwlock_unlock(&blokada);test_errno("pthread_rwlock_unlock");ms_sleep(317);}returnNULL;}//------------------------------------------------------------------------/* wątek tylko odczytuje wartość */void*czytelnik(void*numer){interrno;while(1){printf(" czytelnik #%d czeka na dostęp\n",(int)numer);errno=pthread_rwlock_rdlock(&blokada);test_errno("pthread_rwlock_rdlock");printf(" czytelnik #%d odczytuje wartość\n",(int)numer);ms_sleep(13);printf(" czytelnik #%d zwalnia blokadę\n",(int)numer);errno=pthread_rwlock_unlock(&blokada);test_errno("pthread_rwlock_unlock");ms_sleep(13);}returnNULL;}//------------------------------------------------------------------------#define N 5 /* liczba wątków */#define K 2intmain(){pthread_tid;inti;pthread_rwlock_init(&blokada,NULL);/* utworzenie K wątków piszących */for(i=0;i<K;i++){errno=pthread_create(&id,NULL,pisarz,(void*)i);test_errno("pthread_create");}/* utworzenie N wątków czytających */for(i=0;i<N;i++){errno=pthread_create(&id,NULL,czytelnik,(void*)i);test_errno("pthread_create");}/* kilka sekund na pracę wątków i koniec */ms_sleep(1500);returnEXIT_SUCCESS;}//------------------------------------------------------------------------voidms_sleep(constunsignedms){structtimespecreq;req.tv_sec=(ms/1000);req.tv_nsec=(ms%1000*1000000);nanosleep(&req,NULL);}//------------------------------------------------------------------------