university of pennsylvania 9/21/00cse 3801 concurrent process synchronization (lock and semaphore)...
TRANSCRIPT
9/21/00 CSE 380 1
University of Pennsylvania
Concurrent Process Synchronization
(Lock and semaphore)CSE 380
Lecture Note 5
Insup Lee
9/21/00 CSE 380 2
University of Pennsylvania
Locks
lock (x) performs
lock: [ if x = false then x := true else go to lock ]
unlock (x) performs
[x := false ]
E.g.,
var x : booleanparbegin P1: ... lock(x); CS_1; unlock(x) … … Pn: ... lock(x); CS_n; unlock(x) …parend
9/21/00 CSE 380 3
University of Pennsylvania
Properties
1. Starvation is possible.
2. Busy waiting.
3. Different locks may be used for different shared resources.
4. Proper use not enforced. E.g., forget to lock.
9/21/00 CSE 380 4
University of Pennsylvania
How to implement locks
Requires an atomic (uninterruptable at the memory level) operations like test-and-set or swap.
atomic function TestAndSet (var x: boolean): boolean; begin TestAndSet := x; x := true; end
procedure Lock (var x : boolean); while TestAndSet(x) do skip od;
procedure Unlock (var x: boolean); x := false;
(1) If not supported by hardware, TestAndSet can be implemented by disabling and unabling interrupts.(2) Lock can also be implemented using atomic swap(x,y).
9/21/00 CSE 380 5
University of Pennsylvania
Hardware Instructions
Examples: (1) VAX 11, (2) B6500
MIPS -- Load-Linked/Store Conditional (LL/SC)
Pentium -- Compare and Exchange, Exchange, Fetch and Add
SPARC -- Load Store Unsigned Bit (LDSTUB) in v9
PowerPC -- Load Word and Reserve (lwarx) and Store Word Conitional (stwcx)
9/21/00 CSE 380 6
University of Pennsylvania
(1) VAX 11
BBSSI Branch on Bit Set and Set Interlocked.BBCCI Branch on Bit Clear and Clear Interlocked.
op bitpos, var, displacement
Operation: teststate = if {BBSSI} then 1 else 0 {set interlock} tmp := bit bit := teststate {release interlock} if tmp = teststate then pc := pc + displacement fi
Busy waiting -- set bit and if already set then go to 1$ 1$: BBSSI bit, base, 1$
9/21/00 CSE 380 7
University of Pennsylvania
(2) B6500
Read with lock operation.SPIN: If RDLK (x) then go to SPIN;
RDLK(x)
register memoryA: addr of x B: 1 <--------> x:
Swap the contents of B and x in one memory cycle and return B.
9/21/00 CSE 380 8
University of Pennsylvania
Semaphores
P V Dijkstra ‘65 wait signal Per Brinch Hansen
The semaphore has a value that is invisible to the users and a queue of processes waiting to acquire the semaphore.
type semaphore = record value : integer; L : list of process; end
P(S):[ S.value := S.value-1; if S.value < 0 then add this process to S.L; block; end if ]V(S):[ S.value := S.value + 1; if S.value <= 0 then remove a process P from S.L; wakeup(P); end if ]
9/21/00 CSE 380 9
University of Pennsylvania
Properties of semaphore
parbegin S.value = 1 P1: ... P(S); CS1; V(S); ... P2: ... P(S); CS2; V(S); ... . . . Pn: ... P(S); CSn; V(S); ...parend
PropertiesNo busy waitingMay starve unless FCFS (scheduling left to the implementer of semaphores)Can handle multiple users by proper initialization. Example: 3 tape driversCan implement scheduling on an precedence graph.
9/21/00 CSE 380 10
University of Pennsylvania
More properties and examples
e.g. P2 P1 P4 P3 P6 P5
P1: Do Work P2: P(S12) P3: P(13) V(S12) Do Work Do Work V(S13) V(S24) V(S34) V(S35)5 Proper use can't be enforced by compiler.
e.g. P(S) V(S) CS CS V(S) P(S)
e.g. S1, S2 P1: P(S1) P2: P(S2)
P(S2) P(S1) CS CS V(S2) V(S1) V(S1) V(S2)
9/21/00 CSE 380 11
University of Pennsylvania
Classical problems
• The bounded buffer problem
• The readers and writers problems
• The sleeping barber problem
• The dining philosophers problem
9/21/00 CSE 380 12
University of Pennsylvania
The Producer-Consumer Problem
bounded buffer (of size n) one set of processes (producers) write to it one set of processes (consumers) read from it
semaphore: full = 0 /* counting semaphores */ empty = n mutex = 1 /* binary semaphore */
process Producer process Consumer do forever do forever . P(full) /* produce */ P(mutex)
. /* take from buffer */ P(empty) V(mutex) P(mutex) V(empty)
/* add to buffer */ . V(mutex) /* consume */ V(full) . end end
9/21/00 CSE 380 13
University of Pennsylvania
The Dining Philosopher Problem
• Five philosopher spend their lives thinking + eating.• One simple solution is to represent each chopstick by a
semaphore.• P before picking it up & V after using it.
var chopstick: array[0..4] of semaphores=1philosopher i
repeat P( chopstock[i] ); P( chopstock[i+1 mod 5] ); ... eat ... V( chopstock[i] ); V( chopstock[i+1 mod 5] ); ... think ... forever
• Is deadlock possible?
9/21/00 CSE 380 14
University of Pennsylvania
Number of possible states
o 5 philosophers
o Local state (LC) for each philosoper
• thinking, waiting, eating
o Glabal state = (LC 1, LC 2, …, LC5)
• E.g., (thinking, waiting, waiting, eating, thinking)
• E.g., (waiting, eating, waiting, eating, waiting)
o So, the number of global states are 3 ** 5 = 243
o Actually, it is a lot more than this since waiting can be
• Waiting for the first fork
• Waiting for the second fork
9/21/00 CSE 380 15
University of Pennsylvania
Number of possible behaviors
• Sequence of states
• Initial state: (thinking,thinking,thinking,thinking,thinking)
• The number of possible behaviors = 5 x 5 x 5 x …
• Deadlock state: (waiting,waiting,waiting,waiting, waiting)
• Given the state transition model of your implementation, show that it is not possible to reach the deadlock state from the initial state.
9/21/00 CSE 380 16
University of Pennsylvania
The Readers and Writers Problem
Shared data to be accessed in two modes: reading and writing.
– Any number of processes permitted to read at one time
– writes must exclude all other operations.
Read WriteRead Y N conflictWrite N N matrix
Intuitively:
Reader: | Writer: when(no_writers==0) do | when(no_readers==0 no_readers=no_readers+1 | and no_writers==0) do | no_writers = 1 | <read> | <write> | no_readers=no_readers-1 | no_writers = 0 . | . . | .
9/21/00 CSE 380 17
University of Pennsylvania
A Solution to the R/W problem Semaphore:
mutex = 1 /* mutual excl. for updating readcount */ wrt = 1 /* mutual excl. writer */
int variable: readcount = 0
Reader: P(mutex) readcount = readcount + 1 if readcount == 1 then P(wrt) V(mutex) <read> P(mutex) readcount = readcount – 1 if readcount == 0 then V(wrt) V(mutex)
Writer: P(wrt) <write> V(wrt)
Notes: wrt also used by first/last reader that enters/exits critical section. Solution gives priority to readers in that writers can be starved by stream of readers.
9/21/00 CSE 380 18
University of Pennsylvania
2nd assignment
• Use semaphores
• Need to have shared memory between processes to allocate semaphores
9/21/00 CSE 380 19
University of Pennsylvania
Semaphores
A semaphore is a non-negative integer count and is generally used to coordinate access to resources
System calls:• int sema_init(sema_t *sp, unsigned int count, int type,
void * arg): Initialize semaphores pointed to by sp to count. type can assign several different types of behavior to a semaphore
• int sema_destroy(sema_t *sp); destroys any state related to the semaphore pointed to by sp. The semaphore storage space is not released.
• int sema_wait(sema_t *sp); blocks the calling thread until the semaphore count pointed to by sp is greater than zero, and then it atomically decrements the count.
9/21/00 CSE 380 20
University of Pennsylvania
Semaphores (cont’d)
• int sema_trywait(sema_t *sp); atomically decrements the semaphore count pointed to by sp, if the count is greater than zero; otherwise, it returns an error.
• int sema_post(sema_t *sp); atomically increments the semaphore count pointed to by sp. If there are any threads blocked on the semaphore,one will be unblocked.
9/21/00 CSE 380 21
University of Pennsylvania
Example
The customer waiting-line in a bank is analogous to the synchronization scheme of a semaphore using sema_wait() and sema_trywait():
9/21/00 CSE 380 22
University of Pennsylvania
Semaphores example #include <errno.h>
#define TELLERS 10 sema_t tellers; /* semaphore */
int banking_hours(), deposit_withdrawal;
void *customer(), do_business(), skip_banking_today();
...
sema_init(&tellers, TELLERS, USYNC_THREAD, NULL);
/* 10 tellers available */
while(banking_hours())
pthread_create(NULL, NULL, customer, deposit_withdrawal);
...
void * customer(int deposit_withdrawal)
{
int this_customer, in_a_hurry = 50;
this_customer = rand() % 100;
9/21/00 CSE 380 23
University of Pennsylvania
if (this_customer == in_a_hurry) {
if (sema_trywait(&tellers) != 0)
if (errno == EAGAIN) { /* no teller available */
skip_banking_today(this_customer);
return;
} /* else go immediately to available teller and decrement tellers */
}
else
sema_wait(&tellers); /* wait for next teller, then proceed, and decrement tellers */
do_business(deposit_withdrawal);
sema_post(&tellers); /* increment tellers;
this_customer's teller
is now available */
}