Øvelse+5+-+Thread+synchronization+1

=Exercise 1 Mutex and/or Semaphore= Does it matter, in both scenarios described above, which of the two is used? Present your arguments.

//Both scenarios can be used. In Exercise 2, senarios 4.1.3, we will use mutexes, because there only are one thread in the Exercise, the thread are not dependce of another thread(For more see Exercise 2, on this page).//

//Mutexes are owned bu one thread at a time, only the "taker" can release the mutex. There are to operations on a Mutex lock(Mutex) and unlock(mutex). If a variable/thread in the "taker" are lock(Mutex) another "taker" can't use the variable/thread before the first "taker" release it.//
 * //Mutex://**

//Semaphores are used to enforce mutual exclusion or rather signaling. Semaphores are not owned by one thread at a time, all can release. There are to operations to lock a Semaphore take(s) and release(s).//
 * //Semaphore://**

=Exercise 2 Using the synchronization primitive= Fix the problem for both scenarios(Øvelse 4.1.2 and Øvelse 4.1.3). Verify that your solution works for the second scenario1.

code format="cpp" /*   In this execise, we will use mutexes to solve the problem. We have chosen to use mutexes, because it is lot easier to use than Semaphores. In this case have we one thread there not have any dependcen to other threads, so we must only lock and unlock it.
 * Øvelse 4.1.3 - Mutexes**

To see how to easy use mutexes look at: http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
 * 1) include
 * 2) include 
 * 3) include 
 * 4) include "Vector.hpp"
 * 1) include "Vector.hpp"

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //Global mutex variable. /* PTHREAD_MUTEX_INITIALIZER: In cases  where default  mutex     attributes are appropriate, the macro PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes  that  are statically allocated. The effect shall be equivalent to dynamic ini- tialization by a call to pthread_mutex_init with parameter attr spec- ified as NULL, except that no error checks are performed Vector v; //Global Vector object

void *writer(void *ID) // ***OBS*** Must be a pointer { pthread_mutex_lock(&mutex); /*   pthread_mutex_lock(&): The mutex  object  referenced  by  mutex  shall be  locked by calling pthread_mutex_lock. If the mutex  is already locked,  the  calling thread shall  block until the mutex becomes available. This operation shall return with the mutex object referenced by mutex in  the locked state with the calling thread as its owner. if(v.setAndTest((int)ID) == false) std::cout << "setAndTest Error! \n"; else std::cout << "setAndTest succes! \n"; pthread_mutex_unlock(&mutex); /*     pthread_mutex_unlock(&): The pthread_mutex_unlock function shall release the mutex object referenced by mutex. The manner  in which a mutex is released is dependent upon the  mutex's  type  attribute. If there  are threads blocked on the mutex object referenced by mutex when pthread_mutex_unlock is  called, resulting in  the  mutex  becoming available, the scheduling  policy  shall determine which thread shall acquire the mutex. */ }

int main { int antal; std::cout << "Have many threads?: "; std::cin >> antal;

pthread_t thread[antal];

for(int i = 0; i < antal; i += 1) {   pthread_create(&thread[i], NULL, writer, (void*)i); //Create a new thread sleep(1); }

pthread_exit(NULL); //Exit terminate the calling thread

return 0; } code =Exercise 3 Ensuring proper unlocking= The method for data protection in Exercise 2 has one problem. The programmer is not forced to release the mutex/semaphore after he updates the shared data. Using the Scoped Locking idiom can enforce this.

The idea behind the Scoped Locking idiom1 is that you create a class ScopedLocker which is passed a Mutex on construction. The ScopedLocker takes the Mutex object in its constructor and holds it until its destruction - thus, it holds the mutex as long as it is in scope. Implement the class ScopedLocker and use it in class Vector to protect the resource. Verify that this improvement works.

//To solve the problem we chosen to make a ScopedLocker.hpp file there implement a constructer, destructer and a mutex. When a ScopedLock object is called in a thread, the constructer lock the mutex, when the thread end the scrope where the ScopedLocker are in, the destructer will be called and the mutex will be unlocked again. By making this Scopedlocker, we are free to worry about having to unlock the mutex.// code format="cpp"
 * 1) pragma once
 * 2) include

class ScopedLocker { public: ScopedLocker(pthread_mutex_t &m) : mutex(m) {pthread_mutex_lock(&mutex);} ~ScopedLocker {pthread_mutex_unlock(&mutex);}

private: pthread_mutex_t &mutex;

}; code

//If we use the ScopedLocker.hpp in the vector.h class, from execise 4.1.3, we can ignore to lock and unlock the shared data when the vector class has been used. THIS IS GENIOUS.//

=Exercise 4 On target= Finally recompile your solution for Exercise 3 for target and verify that it actually works here as well.

//It works fine on the target, only remember to compile it to target!//