Professional Documents
Culture Documents
•Condition Variables
Erol Sahin
URL: http://kovan.ceng.metu.edu.tr/ceng334
Week 2 13/03/07 1
Semaphores
Higher-level synchronization
construct Semaphore
1
Producer/Consumer: naïve implementation
Producer Consumer
int count = 0;
Producer() { Consumer() {
int item; int item;
while (TRUE) { while (TRUE) {
item = bake(); if (count == 0) sleep();
if (count == N) sleep(); item = remove_item();
insert_item(item); count = count – 1;
count = count + 1; if (count == N-1)
if (count == 1) wakeup(producer);
wakeup(consumer); eat(item);
} }
} }
What's wrong with this code? What if we context switch right here??
Producer Consumer
Semaphore mutex = 1;
Semaphore empty = N;
Semaphore full = 0;
Consumer() {
Producer() {
int item;
int item;
while (TRUE) {
while (TRUE) {
down(full);
item = bake();
down(mutex);
down(empty);
item = remove_item();
down(mutex);
up(mutex);
insert_item(item);
up(empty);
up(mutex);
eat(item);
up(full);
}
}
}
}
2
Readers/Writers Problem
W
R
R
R
Reader/Writers Problem
Single shared object
But, only one thread should be able to write to the object at a time
(And, not interfere with any readers...)
Conditions:
A Reader should only wait for a Writer to complete its do_write().
A Reader should not wait for other Readers to complete their do_read().
The Writer should wait for the other Writers to complete their do_write().
The Writer should wait for all the Readers to complete their do_read().
3
Readers-Writers Problem
One issue we need to settle, to clarify problem statement.
Suppose that a writer is active and a mixture of readers and writers now shows up.
Who should get in next?
Or suppose that a writer is waiting and an endless of stream of readers keeps
showing up. Is it fair for them to become active?
Reader/Writers
4
Issues with Semaphores
Much of the power of semaphores derives from calls to
down() and up() that are unmatched
See previous example!
Monitors
A high-level abstraction that provides a convenient and
effective mechanism for process synchronization
Only one process may be active within the monitor at a time
10
5
Monitor with Condition Variables
condition x, y;
11
6
Bounded Buffer using CV's
int theArray[ARRAY_SIZE], size; int get() {
Object theLock; int item;
synchronized(theLock) {
void put(int val) { while (size == 0) {
synchronized(theLock) { theLock.wait();
while (size == ARRAY_SIZE) { }
theLock.wait(); item = getItemFromArray()
} size--;
addItemToArray(val); if (size == ARRAY_SIZE-1)
size++; theLock.notify();
if (size == 1) }
theLock.notify(); return item;
}
} }
7
How to fix this problem?
int theArray[ARRAY_SIZE], size; int get() {
Object theLock; int item;
synchronized(theLock) {
void put(int val) { while (size == 0) {
synchronized(theLock) { theLock.wait();
while (size == ARRAY_SIZE) { }
theLock.wait(); item = getItemFromArray()
} size--;
addItemToArray(val); if (size == ARRAY_SIZE-1)
size++; theLock.notifyAll();
if (size == 1) }
theLock.notifyAll(); return item;
}
} }
Every notifyAll() will cause all threads to wake up and re-check the
empty or full condition.
Could be inefficient if a lot of threads are involved...
Monitors
This style of using locks and CV's to protect access to a shared
object is often called a monitor
Think of a monitor as a lock protecting an object, plus a queue of waiting threads.
Shared data
Waiting threads
8
Monitors
unlocked
Shared data
Methods accessing
shared data
Monitors
locked
Shared data
zzzz...
Methods accessing
zzzz... shared data
9
Monitors
Monitor stays locked! locked
(Lock now owned by
different thread...)
Shared data
notify()
Methods accessing
zzzz... shared data
Monitors
locked
Shared data
notify()
Methods accessing
shared data
10
Monitors
locked
Shared data
Methods accessing
shared data
CVs in Java
In Java, a thread can only call wait(), notify(), or notifyAll() if it
holds the lock of the associated object
Object foo;
/* NOT ALLOWED!!! */
foo.notify();
/* This is ok ... */
synchronized(foo) { foo.notify(); }
Why?
11
CVs in Java
In Java, a thread can only call wait(), notify(), or notifyAll() if it
holds the lock of the associated object
Object foo;
/* NOT ALLOWED!!! */
foo.notify();
/* This is ok ... */
synchronized(foo) { foo.notify(); }
Why?
Want to avoid common race conditions!
12
Hoare vs. Mesa Monitor Semantics
The monitor notify() operation can have two different meanings:
if (n==0) {
wait(not_empty); // If nothing, sleep
}
removeItemFromArray(val); // Get next item
26
13
Revisit: Readers/Writers Problem
Correctness Constraints:
Readers can access database when no writers
Writers can access database when no readers or writers
Only one thread manipulates state variables at a time
27
Monitor ReadersNWriters {
int WaitingWriters, WaitingReaders,NReaders, NWriters;
Condition CanRead, CanWrite;
28
14
Readers and Writers
Monitor ReadersNWriters {
int WaitingWriters, WaitingReaders,NReaders, NWriters;
Condition CanRead, CanWrite;
29
Monitor ReadersNWriters {
int WaitingWriters, WaitingReaders,NReaders, NWriters;
Condition CanRead, CanWrite;
30
15
Readers and Writers
Monitor ReadersNWriters {
int WaitingWriters, WaitingReaders,NReaders, NWriters;
Condition CanRead, CanWrite;
31
32
16
Readers and Writers
Monitor ReadersNWriters {
int WaitingWriters, WaitingReaders,NReaders, NWriters;
Condition CanRead, CanWrite;
33
34
17
Readers and Writers
Monitor ReadersNWriters {
int WaitingWriters, WaitingReaders,NReaders, NWriters;
Condition CanRead, CanWrite;
35
Similarly, when a reader finishes, if it was the last reader, it lets a writer
in (if any is there)
36
18
Readers and Writers
Monitor ReadersNWriters {
int WaitingWriters, WaitingReaders,NReaders, NWriters;
Condition CanRead, CanWrite;
37
… this is mostly fair, although once it lets a reader in, it lets ALL waiting readers in all at
once, even if some showed up “after” other waiting writers
38
19
The Big Picture
The point here is that getting synchronization right is hard
20