Sie sind auf Seite 1von 30

Semaphores and Monitors

CIS450 Winter 2003

Professor Jinhua Guo


1

Mutual Exclusion with Swap


Initially, s == false; entry () { bool spin = true; Swap(spin, s); while (spin) Swap(spin, s); }

exit() { s = false; }
2

Semaphores (Dijkstra)
Synchronization tool that does not require busy waiting. Semaphore is an object contains a (private) integer value and 2 operations.
P operation, also called Down or Wait
Take a resource

V operation, also called Up or Signal


Release a resource

Semaphores are resource counters.


3

Semaphore Implementation
Define a semaphore as a record typedef struct { int value; struct process *L; } semaphore; Assume two simple operations:
block(), suspends the process that invokes it. wakeup(P), changes the thread from the waiting state to the ready state.
4

Implementation
Semaphore operations now defined as P(S): S.value--; if (S.value < 0) { add this process to S.L; block(); } V(S): S.value++; if (S.value <= 0) { remove a process P from S.L; wakeup(P); } The P and V operations are atomic.
5

Critical Sections with Semaphores


semaphore mutex = 1; entry() P(mutex); exit() V(mutex);

For mutual exclusion, initialize semaphore to 1.


6

Semaphore as a General Synchronization Tool


Execute B in Pj only after A executed in Pi Use semaphore flag initialized to 0 Code: Pi Pj A P(flag) V(flag) B
7

Bounded Buffer Problem


There is one Buffer object used to pass objects from producers to consumers. The problem is to allow concurrent access to the Buffer by producers and consumers, while ensuring that
1. The shared Buffer data structure is not screwed up by race conditions in accessing it. 2. Consumers don't try to remove objects from Buffer when it is empty. 3. Producers don't try to add objects to the Buffer when it is full.
8

Bounded Buffer
(1 producer, 1 consumer) char buf[n], int front = 0, rear = 0; semaphore empty = n, full = 0; Producer() while (1) { produce message m; P(empty); buf[rear] = m; rear = rear +1; V(full); } Consumer () while (1) { P(full); m = buf[front]; front = front + 1; V(empty); consume m; }
9

Bounded Buffer
(multiple producers and consumers) char buf[n], int front = 0, rear = 0; semaphore empty = n, full = 0, mutex = 1; Producer() while (1) { produce message m; P(empty); P(mutex); buf[rear] = m; rear = rear +1; V(mutex); V(full) } Consumer () while (1) { P(full); P(mutex); m = buf[front]; front = front + 1; V(mutex); V(empty); consume m; }
10

Deadlock and Starvation


Deadlock two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes. Let S and Q be two semaphores initialized to 1 P0 P1 P(S); P(Q); P(Q); P(S); V(S); V(Q); V(Q); V(S); Starvation indefinite blocking. A process may never be removed from the semaphore queue in which it is suspended.
11

Readers-Writers Problem
Given a database
Can have multiple readers at a time dont ever modify database Only one writer will modify database

The problem has many variation

12

Readers-Writers Problem Semaphore Solution


Shared data
semaphore mutex = 1, wrt = 1; int readcount = 0;

Writer Process
writeEnter () { P(wrt); }

writeExit () { V(wrt); }
13

Reader Process
readEnter () { P(mutex); readcount++; if (readcount == 1) P(wrt); V(mutex); } readExit() { P(mutex); readcount--; if (readcount == 0) V(wrt); V(mutex); }
14

Dining-Philosophers Problem

Shared data semaphore chopstick[5]; Initially all values are 1

15

Dining-Philosophers Problem
Philosopher i: do { P(chopstick[i]) P(chopstick[(i+1) % 5]) eat V(chopstick[i]); V(chopstick[(i+1) % 5]); think } while (1);

16

Dining-Philosophers Problem
(Deadlock Free)
Philosopher i: do { if (i ! = 0) { P(chopstick[i]); P(chopstick[i+1]); eat V(chopstick[i]); V(chopstick[i+1]); } else { P(chopstick[1]); P(chopstick[0]); eat V(chopstick[1]); V(chopstick[0]); } think } while (1);
17

Problems with Semaphores


Used for 2 independent purposes
Mutual exclusion Condition Synchronization

Hard to get right


Small mistake easily leads to deadlock

May want to separate mutual exclusion, condition synchronization


18

Monitors (Hoare)
Abstract Data Type
Consists of vars and procedures, like C++ class. 3 key differences from a regular class:
Only one thread in monitor at a time (mutual exclusion is automatic); Special type of variable allowed, called condition variable
3 special ops allowed only on condition variables: wait, signal, broadcast

No public data allowed (must call methods to effect any change)


19

Monitors
monitor monitor-name { shared variable declarations procedure body P1 () { ... } procedure body P2 () { ... } procedure body Pn () { ... } { initialization code } }
20

Monitors
To allow a process to wait within the monitor, a condition variable must be declared, as condition x, y, cond; Given a condition variable cond
cond.wait():
thread is put on queue for cond, goes to sleep

cond.signal():
if queue for cond not empty, wakeup one thread

cond.broadcast
wakeup all threads waiting on queue for cond
21

Schematic View of a Monitor

22

Monitor With Condition Variables

23

Semantics of Signal
Signal and Wait (Hoare)
signaller immediately gives up control thread that was waiting executes

Signal and Continue (Java, Pthread, Mesa)


signaller continues executing thread that was waiting put on ready queue when thread actually gets to run
State may have changed! Use while, not if
24

Monitor Solution to Critical Section


Just make the critical section a monitor routine!

25

Readers/Writers Solution Using Monitors


Similar idea to semaphore solution
Simpler, because dont worry about mutex

When cant get into database, wait on appropriate condition variable When done with database, signal others Note: cant just put code for reading database and code for writing database in the monitor (couldt have >1 reader)
26

Difference between Monitors and Semaphores


Monitors enforce mutual exclusion P() vs Wait
P blocks if value is 0, Wait always blocks

V() vs Signal
V either wakes up a thread or increments value Signal only has effect if a thread waiting

Semaphores have memory


27

Implementing Monitors using Semaphores


Shared vars:
semaphore mutex = 1(one per monitor) semaphore c = 0; (one per condition var) int nc = 0; (one per condition var)

Monitor entry: P(mutex); Monitor exit: V(mutex);

28

Implementing Monitors using Semaphores


cond->Wait(mutex):
nc++; V(mutex); P(c); P(mutex);

cond->Signal():
if (nc > 0) { nc--; V(c); }
29

Java-style monitors
Integrated into the class mechanism
Annotation synchronized can be applied to a member function
This function executes with implicit mutual exclusion

Wait, Signal, and Broadcast are called mon wait, notify, and notifyAll, respectively

30

Das könnte Ihnen auch gefallen