View
219
Download
0
Tags:
Embed Size (px)
Citation preview
1
Last Time: Locks & Semaphores
Implementing locks Test & Set Busy waiting Block waiting
Semaphores Generalization of locks
2
This Time: More Synch Primitives
Reader-Writer Locks Monitors Condition Variables
3
Reader/Writers Problem
Suppose one object shared among many threads
Each thread is either a reader or a writer Readers – only read data, never modify Writers – read & modify data
How should we control access to this object? Which synchronization primitive?
RW R W R
4
Single Lock
thread A
Lock.acquire()
Read data
Lock.release()
thread B
Lock.acquire()
Modify data
Lock.release()
thread C
Lock.acquire()
Read data
Lock.release()
thread D
Lock.acquire()
Read data
Lock.release()
thread E
Lock.acquire()
Read data
Lock.release()
thread F
Lock.acquire()
Modify data
Lock.release()
Drawbacks of this solution?
5
Readers/Writers Optimization
Single lock: safe, but limits concurrency Only one thread at a time, but…
Safe to have simultaneous readers! Allow only one writer at a time Must guarantee mutual exclusion for
writers How to implement this?
6
Reader-Writer Locks
New synchronization operator:reader-writer lock Multiple processes acquire reader-writer
lock in reader mode One process acquires reader-writer lock in
writer mode
Can be built with standard synch primitives E.g., semaphores
7
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
8
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
reader
9
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
reader
10
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
reader
reader
11
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
reader
reader
12
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
reader
reader
reader
13
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
reader
reader
reader
14
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
reader
reader
reader
writer
15
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
reader
reader
writer
16
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
reader
reader
writer
writer
17
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
reader
writer
writer
18
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
writer
writer
19
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
writer
writer
20
Readers/Writers Algorithm
As long as there are no writers Let readers in
If no readers or writers Let one writer in
writer
writer reader
21
Readers/Writers Algorithm
As long as there are no writers in critical section Let readers in
If no readers or writers in critical section Let one writer in
writer
writer readerreader
What happens next?
22
Starvation Problem Two variants:
1. Give reader priority: No reader waits unless writer is already in
2. Give writer priority: Waiting writer always gets served first
Both variants may lead to starvation First: writers may starve Second: readers may starve
Concurrent control with “readers” and “writers”, by P. J. Courtois, F. Heymans, D. L. Parnas
Concurrent reading and writing, by Leslie Lamport, w/o mutual exclusion
23
Implementing Give-reader-priority
Can implement with two semaphores “readerSemaphore”: protect number of
readers “writerSemaphore”: control scheduling
of writers
Control access to a “database” int getValue() void setValue (int n)
24
Implementing Give-reader-priority
class RWDatabase { private Database db; private int readers; private Semaphore readerSemaphore; private Semaphore writerSemaphore; RWDatabase() { readers = 0; readerSemaphore = new Semaphore (1); writerSemaphore = new Semaphore (1); } int read() { … } void write (int n) { … }};
25
Write value
Implementing Give-reader-priorityvoid RWDatabase::write (int v) { writerSemaphore.wait(); db.setValue(v); // Write the value writerSemaphore.signal();};
26
Read, remove reader
Add a reader
Implementing Give-reader-priorityint RWDatabase::read() { int v; readerSemaphore.wait(); readers++; if (readers == 1) { // I’m first reader writerSemaphore.wait(); } readerSemaphore.signal(); v = db.getValue(); readerSemaphore.wait(); readers--; if (readers == 0) { // I’m last reader writerSemaphore.signal(); } readerSemaphore.signal(); return v;}; Who can starve?
27
2-dinning-philosopher Problem
Shared resource: chopsticks Totally 2 philosophers & 2 chopsticks
Philosopher picks up chopstick in increasing order
28
3-dinning-philosopher Problem
Shared resource: chopsticks Totally 3 philosophers & 3 chopsticks
Philosopher picks up chopstick in increasing order
29
Problems withSemaphores & Locks
Much better than load/store Still many drawbacks
Access to semaphores may be anywhere
Not structured Not tied to data they control access
to Difficult to detect error
30
This Time: More Synch Primitives
Reader-Writer Locks Monitors Condition Variables
31
Monitors
Invented by C.A.R. “Tony” Hoare Also invented quicksort, “Hoare triples”
{a > 16} a = sqrt(a); { a > 4 }
Monitor: High-level synchronization construct Private data with public methods
operating on data All methods synchronized
Access of data inside monitor is mutual exclusive
32
Monitors syntax
monitor monitor-name {// shared variable
declarationsprocedure P1 (…) { ….
}…
procedure Pn (…) {……}
Initialization code ( ….) { … }
…}
33
Condition Variables
Another synchronisation primitive condition x; Two operations on a condition
variable: x.wait () – a process that invokes
the operation is suspended. x.signal () – resumes one of
processes (if any) that invoked x.wait ()
34
Condition Variable in Linux
Wait for some condition to be true Then do some action. If condition not true:
Release lock temporarily Waiting inside critical sections
35
Condition Variable in Linux: Syntax
pthread_cond_t cond; pthread_cond_init (&cond, NULL); //initialize condition variable
...pthread_mutex_lock(&my_mutex);while(!certain_condition) pthread_cond_wait(&cond, &mutex); //waitpthread_mutex_unlock(&my_mutex);...pthread_cond_signal(&cond); //signal
pthread_cond_t cond; pthread_cond_init (&cond, NULL); //initialize condition variable
...pthread_mutex_lock(&my_mutex);while(!certain_condition) pthread_cond_wait(&cond, &mutex); //waitpthread_mutex_unlock(&my_mutex);...pthread_cond_signal(&cond); //signal
36
Condition Variables Example: Reader-writer Problem
A single reader and writer Share a buffer which holds one
item (an integer) Reader: only read when there is
item in buffer Writer: only write when there is
space in buffer
37
Condition Variable Example: Reader-writer Problem
#include <pthread.h>
#include <stdio.h>
#include <stdio.h>
int buffer_has_item = 0;
int buffer;
pthread_mutex_t mutex;
pthread_cond_t cond;
void * reader_function(void *)
{
while(1){
pthread_mutex_lock( &mutex );
while(buffer_has_item == 0)pthread_cond_wait(&cond, &mutex);
if ( buffer_has_item == 1) {
printf("reader consumes one item: %d.\n", buffer);
buffer_has_item = 0;
}
pthread_mutex_unlock( &mutex );
}
}
38
Condition Variable Example: Reader-writer Problemvoid writer_function(void){ while(1) { pthread_mutex_lock( &mutex ); if( buffer_has_item == 0 ){
buffer = rand() ;printf("writer produces one item: %d\n", buffer);buffer_has_item = 1;pthread_cond_signal(&cond);
} pthread_mutex_unlock( &mutex ); }}
int main(){ pthread_t reader;
pthread_mutex_init(&mutex, NULL);
if (pthread_cond_init (&cond, NULL) == -1){ printf("Error setting up semaphore condition signal"); exit(-1); } pthread_create( &reader, NULL, reader_function, NULL); writer_function(); return 1;}
39
Condition Variables Example: Dining-philosophers Problem
Shared resource: chopsticks Totally 5 philosophers & 5 chopsticks
Philosopher may pick up chopsticks only when both available
40
Monitor Example: Dining-philosophers Problem
Shared resource: chopsticks Totally 5 philosophers & 5 chopsticks
41
Monitor Example: Dining-philosophers Problem
monitor DP {
enum { THINKING; HUNGRY, EATING) state [5] ;condition self [5];
void pickup (int i) { state[i] = HUNGRY; test(i); if (state[i] != EATING) self [i].wait;}
void putdown (int i) { state[i] = THINKING; // test left and right neighbors test((i + 4) % 5); test((i + 1) % 5);
} void test (int i) {
if ( (state[(i + 4) % 5] != EATING) && (state[i] == HUNGRY) && (state[(i + 1) % 5] != EATING) ) { state[i] = EATING ; self[i].signal () ; }
} initialization_code() {
for (int i = 0; i < 5; i++) state[i] = THINKING;}
}
• Philosopher: 0 … 4
• Philosopher may pick up chopsticks only when both available
• Philosopher i
dp.pickup(i)
eat;
dp.putdown(i)
42
Summary
Multi-Reader-Writer problem Permit concurrent reads Implementable with semaphores
Dinning philosopher problem Monitors
Tie data, methods with synchronization Condition Variables
Release lock temporarily Waiting inside critical sections