Introduction
In this exercise you will get some routine
in using thread synchronization mechanisms. First,
you will rectify the shared data problem
you experienced in Exercise Posix
Threads, using a
mutex or a semaphore. Then, you will write
the ScopeLocker class that utilizes RAII to ensure
that locks are always relinquished.
Prerequisites
In order to complete this exercise, you
must:
·
have
completed Exercise Posix Threads
Goal
·
To
make you able to di_erentiate between di_erent kinds of a mutex and semaphores
and decide which one is the right one for synchronization issues
·
To
give you routine in de_ning and using thread synchronization mechanisms under
Linux
·
To
make you understand how the ScopedLocker
idiom can aid you in handling
Mutexes.
The problem in Exercises Sharing data between threads and Sharing a Vector class between
threads from Posix Threads is that all threads share and utilize a
resource and that resource
is not protected. This is illustrated in
the fact that a thread could not
necessarily complete
its read or write operation uninterrupted.
When a thread was interrupted in the read or write
of the shared resource, the shared
resource could be left in an inconsistent state and an
error
would be reported. This problem can be
rectified using a mutex/semaphore.
Exercise 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?
Mutex:
First initializing:
pthread_mutex_t mutex1 =
PTHREAD_MUTEX_INITIALIZER;
//creates and initializing a mutex.
Then add:
pthread_mutex_lock(
&mutex1 );
//
code you want to protect
pthread_mutex_unlock(
&mutex1 );
Code:
Semaphore: remember to include <semaphore.h>
First create a semaphore:
sem_t
s; //global
Then initialize it:
sem_init(&s,
0, 1); //ref to sem, shared between threads, init value.
// placed in start of main()
Then add:
sem_wait(&s);
//decreases sem count
//
code you want to protect
sem_post(&s);
//increases sem count
Code:
Both is executed without errors.
In both scenarios mutex and semaphore could be used.
If you use semaphore you should be aware that multiple threads could access the
area you are trying to protect. This can happen if one increment the semaphore
more times than is supposed. This is not a problem with the mutex, since only
one thread can have the lock at a time. When there is only one thread that may
have the lock at a time, you can end up in a deadlock if you forget to release
it. But a similar problem can occur if you do not increment the semaphore.
So there are advantages and disadvantages to both. But
when we allow only one thread to use a piece of code at a time, then mutex is a
good solution
Exercise 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.
Mutex:
Locking mechanism with only one owner.
Can’t be used as a signaling mechanism.
You will add conditionals.
Semaphore:
Locking mechanism with multiple owners.
Can be used as a signaling mechanism.
Exercise 3 Ensuring proper unlocking
The method for data protection in Exercise
1 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 idiom 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. You only need to make it work with a Mutex.
Code:
ScopedLocker.h
Vector.hhp
Exercise 4 On target
Finally recompile your solution for
Exercise 3 for target and verify that it actually works here
as well.
No
errors when running on target.
Exercise 1:
SvarSletThe goal with this exercise is to fix the vector problem using a mutex and a semaphore. By doing this, you will learn what a mutex does and what a semaphore does. In your exercise you have completed this task.
Exercise 2:
The gold with this exercise is to describe the difference between a mutex and a semaphore. In your exercise you have completed this task.
Exercise 3:
The goal with this exercise is to a separate class that locks and unlocks the mutex, when it is constructed and deconstructed. You handle this exercise correctly, and when you call the construction of the ScopeLocker Lock in the setAndTest scope, the mutex locks as expected. When leaving the scope the ScopeLocker deconstructs and unlocks the mutex. Nicely done.
Exercise 4:
The goal with the last exercise was to test on the target arm processor. Though there is no screenshots of you completing this task, it seems you did it right.
Overall good job.
Love, group 48