MUP1+Øvelse+4.1

toc =Øvelse 4.1=

Opgave 1
Hvilken semaphore er den rigtige at bruge i MUP1 Øvelse 3.2? I opgave MUP1 Øvelse 3.2-1 vil binær semaphore være den helt rigtige da vi vil kunne garantere at den tæller 1,2,3...n. Men binær semaphore findes ikke i linux, så vi er nødsaget til at implementere det via 2 tælle semaphorer.

code SEM_ID cs_inc = createCountingSem(1); // default blocked SEM_ID cs_read = createCountingSem(0); int i = 0; code || take(cs_inc); ++i; release(cs_read); code || code take(cs_read); cout << i; release(cs_inc); code ||
 * ~ Pseudo kode||
 * Incrementer thread || Reader thread ||
 * code

I opgave MUP1 Øvelse 3.2-3 og 4 skal vi blot bruge et mutex semaphore.

Opgave 2
Vi har tilføjet mutex beskyttelse til opgave 3.2-4. Vores reelle kode ser ud som nedenstående. code format="cpp" void* writer(void* n){ DATA userTime = *(DATA*)n; while(true) {		pthread_mutex_lock(&threadMutex); // locker med mutex if(!V.setAndTest(userTime.count)) {			cout << "FAIL!!" << endl; }//else { //cout << "utime =" << userTime.utime << endl; //cout << "Threads created " << userTime.numberOfThreads << endl; //}		pthread_mutex_unlock(&threadMutex); // unlocker med mutex usleep(userTime.utime); } code vi har ovenstående kun vist vores tråd funktion, men der er oprettet en mutex som hedder threadMutex og vi husker selvfølgelig os at "ødelægge" mutex'en når vi er færdige med pthread_mutex_destroy funktionen.

Det vi har gjort er egentlig ikke den sikreste metode, vi har efter lidt eftertanke fundet ud af at en udefra kunne skrive en ny writer funktion uden at bruge mutex beskyttelse og bruge den derfor bestemte vi os for at det sikreste ville være at lave mutex beskyttelsen inde i Vektor klassen da det så ville blive gjort selvom writeren ikke var mutex beskyttet. code format="cpp"

class Vector { public: Vector : SIZE(10000) {

vector = new int[SIZE]; set(0); }

~Vector {		delete[] vector; pthread_mutex_destroy(&threadMutex); //nedlægger din mutex }

bool setAndTest(int n)	{ int testRespons; pthread_mutex_lock(&threadMutex); // locker med mutex set(n); testRespons = test(n); pthread_mutex_unlock(&threadMutex); // unlocker med mutex return testRespons; }

private: void set(int n)	{ for(unsigned int i=0; i<SIZE; i++) vector[i] = n;	}

bool test(int n)	{ for(unsigned int i=0; i<SIZE; i++) if(vector[i] != n) return false; return true; }

int* vector; unsigned int SIZE; pthread_mutex_t threadMutex; };

code

Vi prøvede at presse computeren og teste samtidig men ingen fejl kunne spottes på noget tidspunkt overhovedet, så MUTEX implemationen virker :D

Opgave 3
I denne opgave skal vi igen løse opgave 2 men denne gang via en ScopeLocker. Den fungere på den måde at den tager en mutex når klassen bliver oprettet og frigiver den igen når klassen bliver destructed hvilket sker når scoped hvori scopelockeren blev oprettet i forlades. Det smarte ved denne metode er at skulle der ske en execption mellem låsning og frigivelse af en mutex vil mutexen blive frigivet da systemet (glemt navn) sørger for at nedlægge alle objekter i scoped. Med andre ord destructeren i ScopeLocker klassen vil blive kaldt og frigiver dermed mutexen. Så programmet kan kører videre givet det ikke var en system kritisk execption der blev kastet.

code format="cpp"
 * ScopeLocker.h**
 * 1) include 

class ScopeLocker { public: ScopeLocker(pthread_mutex_t *mutex) {		this->mutex = mutex; pthread_mutex_lock(mutex); }	~ScopeLocker {		pthread_mutex_unlock(mutex); } private: pthread_mutex_t *mutex; }; code Det er vigtigt af mutexen er ekstern for ScopeLocker klassen.

Vector klassen med ScopeLockeren implementeret: code format="cpp"
 * Vector.h**
 * 1) include 
 * 2) include 
 * 3) include "ScopeLocker.h"

class Vector { public: Vector : SIZE(10000) {		vector = new int[SIZE]; set(0); }

~Vector {		delete[] vector; pthread_mutex_destroy(&mutex); }

bool setAndTest(int n)	{ ScopeLocker s(&mutex); // create ScopeLocker object which is destoried upon leaving scope set(n); return test(n); // Leaving scope and the mutex is released }

private: void set(int n)	{ for(unsigned int i=0; i<SIZE; i++) vector[i] = n;	}

bool test(int n)	{ for(unsigned int i=0; i<SIZE; i++) if(vector[i] != n) return false; return true; }

int* vector; unsigned int SIZE; pthread_mutex_t mutex; }; code ScopeLockeren bliver implementeret i setAndTest da det ikke er nok at implementere den i set og test da der godt kunne komme en tråd og kalde set inden den første tråd fik testet.