it325 operating systems chapter6. threads can greatly simplify writing elegant and efficient...

12
Synchronizing threads with mutexes IT325 Operating systems Chapter6

Upload: diana-lucas

Post on 19-Jan-2016

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

Synchronizing threads with mutexes

IT325 Operating systems Chapter6

Page 2: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

Threads can greatly simplify writing elegant and efficient programs.

However, there are problems when multiple threads share a common address space, like the variable data in next example.

Synchronizing threads with mutexes

Page 3: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

To understand what might happen, consider the following code:

THREAD 1 THREAD 2 a = data; b = data; a++; b--; data = a; data = b; Now if this code is executed serially (for

instance, THREAD 1 first and then THREAD 2), there are no problems.

However threads execute in an arbitrary order, so consider the following situation:

Example

Page 4: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

THREAD 1 THREAD 2 a = data; b = data; a++; b--; data = a; data = b; [data = data - 1!!!!!!!] So data could end up +1, 0, -1, and there is NO

WAY to know which value! It is completely non-deterministic!

Example

Page 5: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

The solution to this is to provide functions that will block a thread if another thread is accessing data that it is using.

Pthreads use a data type called a mutex to achieve this.

Solution

Page 6: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

A basic mechanism supplied by the pthreads library to solve the data race problem, is called a mutex.

Mutexes have two basic operations, lock and unlock. If a mutex is unlocked and a thread calls lock, the mutex locks and the thread continues. If however the mutex is locked, the thread blocks until the thread holding the lock calls unlock.

Locking a mutex is an atomic operation, meaning that the operating system (or threads library) assures you that if you locked a mutex, no other thread succeeded in locking this mutex at the same time.

What is a mutex?

Page 7: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

In order to create a mutex, we first need to declare a variable of type pthread_mutex_t and then initialize it using the function

int pthread_mutex_init (pthread_mutex_t *mut, const pthread_mutexattr_t *attr); The first argument is a pointer to the mutex. To

second argument is used to set the mutex attributes. To use the default mutex attributes, just pass NULL to it.

example: pthread_mutex_t a_mutex;pthread_mutex_init (&a_mutex, NULL);

Creating and initializing a mutex

Page 8: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

In order to lock a mutex, we may use the function pthread_mutex_lock(). This function attempts to lock the mutex, or block the thread if the mutex is already locked by another thread. In this case, when the mutex is unlocked by the first thread, the function will return with the mutex locked by our thread. Here is how to lock a mutex (assuming it was initialized earlier):

Locking and unlocking a mutex

Page 9: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

int rc = pthread_mutex_lock(&a_mutex); if (rc) { /* an error has occurred */ perror("pthread_mutex_lock"); pthread_exit(NULL); } /* mutex is now locked - do your stuff. */After the thread did what it had to (change variables or data structures, handle file, or whatever it intended to do), it should free the mutex, using the pthread_mutex_unlock() function, like this: rc = pthread_mutex_unlock(&a_mutex); if (rc) { perror("pthread_mutex_unlock"); pthread_exit(NULL); }

Example

Page 10: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

After we finished using a mutex (that is, no thread needs it at all), we should destroy it. However, if only one thread finished with the mutex, it should leave it alive for the other threads that might still need to use it. Once all finished using it, the last one can destroy it using the pthread_mutex_destroy() function: 

rc = pthread_mutex_destroy(&a_mutex); After this call, this variable (a_mutex) may not be

used as a mutex any more, unless it is initialized again. Thus, if one destroys a mutex too early, and another thread tries to lock or unlock it, that thread will get an error from the lock or unlock function.

Destroying a mutex

Page 11: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

Consider the problem we had before and now let us use mutexes: THREAD 1 THREAD 2

pthread_mutex_lock (&a_mutex);

pthread_mutex_lock (&a_mutex);

a = data; /* blocked */

a++; /* blocked */

data = a; /* blocked */

pthread_mutex_unlock (&a_mutex); /* blocked */

b = data;

b--;

data = b;

pthread_mutex_unlock (&a_mutex);

[data is fine. The data race is gone.]

Using a mutex - a short example

Page 12: IT325 Operating systems Chapter6.  Threads can greatly simplify writing elegant and efficient programs.  However, there are problems when multiple threads

Let’s test then modify the thread_add.c program on Assignment7