University of Pennsylvania 9/21/00CSE 3801 Concurrent Process Synchronization (Lock and semaphore)...

Preview:

Citation preview

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 */

}