// Fri Mar 17 17:07:59 CET 2000 // Dinko Korunic, 36355514, kreator@fly.srk.fer.hr // Vjezba 2 iz predmeta Operacijski sustavi 1 // Zadatak // 1. Napisati program koji kreira zadani broj dretvi (D). Sve dretve // trebaju obavljati isti posao: // Posao_dretve(N){ za i=1 do N{ A=A+1; } } // Broj dretvi D i broj N se trebaju unijeti iz komandne linije (npr. // program 2 10000) ili na pocetku izvod/enja glavnog programa. Pocetna // vrijednost varijable A je 1. Kad sve dretve obave svoj posao, treba // ispisati vrijednost varijable A. // 2. Prosiriti program tako da se onemoguci dretvama istovremeno // pisanje i citanje varijable A i to s pomocu MUTEX varijable // zakljucavanja. // Opis rjesenja: // Trivijalno. Vise dretvi koje vrte isti proces, zakljucavanje preko // Mutex, itd. #define _REENTRANT // #define ZAKLJUCAJ #define SOLARIS #include #include #ifndef SOLARIS #include #else #include #include #endif #include class Dretva { long A; #ifdef ZAKLJUCAJ // deklaracija Mutex varijable za zakljucavanje #ifdef SOLARIS mutex_t MutexKljuc; #else pthread_mutex_t MutexKljuc; #endif #endif public: Dretva(const long _A=1) : A(_A) { #ifdef ZAKLJUCAJ // incijaliziramo Mutex varijablu u konstruktoru cout << "Koristim Mutex zakljucavanje." << endl; #ifdef SOLARIS mutex_init(&MutexKljuc, USYNC_THREAD, NULL); #else pthread_mutex_init(&MutexKljuc, NULL); #endif #endif }; ~Dretva() { cout << "Izlazna vrijednost varijable A=" << A << endl; #ifdef ZAKLJUCAJ #ifdef SOLARIS mutex_destroy(&MutexKljuc); #else pthread_mutex_destroy(&MutexKljuc); #endif #endif }; void PosaoDretve(void *N); }; void Dretva::PosaoDretve(void *N) { // funkcija koja svaka dretva izvrsava #ifdef ZAKLJUCAJ // wait preko Mutex varijable, osigurava siguran pristup, // onaj thread koji prvi naleti zakljuca prvi, itd slijedno #ifdef SOLARIS mutex_lock(&MutexKljuc); #else pthread_mutex_lock(&MutexKljuc); #endif #endif for(long i=1; i<=*(int *)N; ++A, ++i); #ifdef ZAKLJUCAJ // odkljucaj #ifdef SOLARIS mutex_unlock(&MutexKljuc); #else pthread_mutex_unlock(&MutexKljuc); #endif #endif } Dretva MojaDretva; void *DretvaMemberFunctionWrapper(void *N) { // wrapper preko kojega se poziva member funkcija MojaDretva.PosaoDretve(N); return NULL; } class ObradiDretvu { #ifdef SOLARIS thread_t *PoljeDretvi; #else pthread_t *PoljeDretvi; #endif int D; long N; void Greska(char *Poruka); void KreirajDretve(void); void VeziDretve(void); public: // konstruktor koji ce obaviti poslove // kreiranja dretvi i vezivanja ObradiDretvu(int _D=2, long _N=10000) : D(_D), N(_N) { #ifdef SOLARIS PoljeDretvi=new thread_t[D]; #else PoljeDretvi=new pthread_t[D]; #endif KreirajDretve(); VeziDretve(); }; ~ObradiDretvu() { cout << "Zavrsio sam s obradom dretvi." << endl; } }; void ObradiDretvu::KreirajDretve(void) { // kreiranje dretvi cout << "Broj dretvi D=" << D << endl << "Broj iteracija N=" << N << endl; for (int i=0; i