ISU E5 - Thread synchronization 1


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.

1 kommentar:

  1. Exercise 1:
    The 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

    SvarSlet