Goals:
To make you able to dierentiate between dierent kinds of a mutex and semaphores and
decide which one is the right one for synchronization issues
To give you routine in dening and using thread synchronization mechanisms under Linux
To make you understand how the ScopedLocker idiom can aid you in handling Mutexes.
1. Using the synchronization primitives:
Fix the Vector problem twice, once using a Mutex and secondly using a Semaphore.
Does it matter, which of the two you use in this scenario? Why, why not?
Which do you prefer and why?
Vector class with mutexes: Vector.hpp
#ifndef VECTOR_HPP_
#define VECTOR_HPP_
#include <pthread.h>
//=======================================================
//
Class: Vector
//
contains a size_-size vector of integers.
//
Use the function setAndTest to set all elements
//
of the vector to a certain value and then test that
//
the value is indeed correctly set
//=======================================================
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
class Vector
{
public:
Vector(unsigned int size = 10000) : size_(size)
{
vector_ = new int[size_];
set(0);
}
~Vector()
{
delete[] vector_;
}
bool setAndTest(int n)
{
pthread_mutex_lock(&m);
set(n);
return test(n);
}
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)
{
pthread_mutex_unlock(&m);
return false;
}
pthread_mutex_unlock(&m);
return true;
}
int* vector_;
unsigned int size_;
};
#endif
Vector class with semaphores: Vector.hpp
#ifndef VECTOR_HPP_
#define VECTOR_HPP_
#include <pthread.h>
#include <semaphore.h>
//=======================================================
//
Class: Vector
//
contains a size_-size vector of integers.
//
Use the function setAndTest to set all elements
//
of the vector to a certain value and then test that
//
the value is indeed correctly set
//=======================================================
sem_t sema;
class Vector
{
public:
Vector(unsigned int size = 10000) : size_(size)
{
sem_init(&sema, 0, 1);
vector_ = new int[size_];
set(0);
}
~Vector()
{
sem_destroy(&sema);
delete[] vector_;
}
bool setAndTest(int n)
{
sem_wait(&sema);
set(n);
return test(n);
}
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)
{
sem_post(&sema);
return false;
}
sem_post(&sema);
return true;
}
int* vector_;
unsigned int size_;
};
#endif
2. Mutexes & Semaphores
At this point you have used both Mutexes and Semaphores and you have been introduced to
their merits.
For each of the two there are 2 main characteristics that hold true. Specify these 2 for both.
Mutexes can only be used to protect data. They are owned by a thread
Semaphores can both be used to protect data and as a counter and signaling. They don't have any owner.
3. Ensuring proper unlocking
The scopedlocker class:
#include <pthread.h>
class Scopedlocker
{
public:
Scopedlocker(pthread_mutex_t *mutexPtr)
{
mutex =
mutexPtr;
pthread_mutex_lock(mutex);
}
~Scopedlocker()
{
pthread_mutex_unlock(mutex);
}
private:
pthread_mutex_t *mutex;
};
#ifndef VECTOR_HPP_
#define VECTOR_HPP_
#include <pthread.h>
#include <semaphore.h>
#include "ScopedLocker.hpp"
//=======================================================
//
Class: Vector
//
contains a size_-size vector of integers.
//
Use the function setAndTest to set all elements
//
of the vector to a certain value and then test that
//
the value is indeed correctly set
//=======================================================
class Vector
{
public:
Vector(unsigned int size = 10000) : size_(size)
{
vector_ = new int[size_];
set(0);
}
~Vector()
{
delete[] vector_;
}
bool setAndTest(int n)
{
Scopedlocker m(&mut);
set(n);
return test(n);
}
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 mut;
};
#endif
4. On Target
We tested Exercise 3 on target and it worked like expected.
This comment has been removed by the author.
ReplyDeleteThe first goal is archived when you use both mutex and semaphores in task 1, and then explain their differns in task 2.
ReplyDeleteThe seccond goal is archived by using mutex and semaphores to deny and use thread synchronization in linux as you do in task 1 and 3
The last goal is to understand how the scopedLocker idiom can aid you in handling Mutexes. You shows how to use and impliment the scopedLocker, and write that it worked as expected, but there is no print of your output to confirm that the scopedLocker works.
All in all we rate that you have completed all the goals, but we are missing some outputs, i would be nice to have a screen of the output.