Concurrency: Classic Problems and Highlevel abstractions - PowerPoint PPT Presentation

1 / 37
About This Presentation
Title:

Concurrency: Classic Problems and Highlevel abstractions

Description:

Reader tasks and writer tasks share a resource, say a database ... enum {thinking, hungry, eating} state[5]; condition self[5]; void pickup(int i) ... – PowerPoint PPT presentation

Number of Views:33
Avg rating:3.0/5.0
Slides: 38
Provided by: patt199
Category:

less

Transcript and Presenter's Notes

Title: Concurrency: Classic Problems and Highlevel abstractions


1
Concurrency Classic Problems and High-level
abstractions
Fred Kuhns (fredk_at_arl.wustl.edu,
http//www.arl.wustl.edu/fredk) Department of
Computer Science and Engineering Washington
University in St. Louis
2
Classical Problems of Synchronization
  • Bounded-Buffer Problem
  • Readers and Writers Problem
  • Dining-Philosophers Problem

3
Bounded-Buffer Problem
  • Shared datasemaphore full, empty,
    mutexInitiallyfull 0, empty n, mutex 1

4
Bounded-Buffer Producer
  • do
  • produce an item in nextp
  • wait(empty) // Decrement free cnt
  • wait(mutex) // Lock buffers
  • add nextp to buffer
  • signal(mutex) // release buffer lock
  • signal(full) // Increment item count
  • while (1)

5
Bounded-Buffer Consumer
  • do
  • wait(full) // decrement item count
  • wait(mutex) // lock buffers
  • remove item from buffer nextc
  • signal(mutex) // release lock
  • signal(empty) // increment free count
  • consume item in nextc
  • while (1)

6
Readers-Writers
  • Reader tasks and writer tasks share a resource,
    say a database
  • Many readers may access a database without fear
    of data corruption (interference)
  • However, only one write may access the database
    at a time (all other readers and writers must be
    locked out of database.
  • Solutions
  • simple solution gives priority to readers.
    Readers enter CS regardless of whether a write is
    waiting
  • writers may starve
  • second solution requires once a write is ready,
    it gets to perform its write as soon as possible
  • readers may starve

7
Readers-Writers Problem
  • The simple solution is presented
  • Shared datasemaphore mutex, wrtInitiallymut
    ex 1, wrt 1, readcount 0

8
Readers-Writers Problem Writer
  • wait(wrt)
  • writing is performed
  • signal(wrt)

9
Readers-Writers Problem Reader
  • wait(mutex)
  • readcount
  • if (readcount 1) // First reader
  • wait(wrt) // then get lock
  • signal(mutex)
  • reading is performed
  • wait(mutex)
  • readcount--
  • if (readcount 0) // Last reader
  • signal(wrt) // then release lock
  • signal(mutex)

10
Dining-Philosophers Problem
  • Shared data
  • semaphore chopstick5
  • Initially all values are 1

11
Dining-Philosophers Problem
  • Philosopher i
  • do
  • wait(chopsticki)
  • wait(chopstick(i1) 5)
  • eat
  • signal(chopsticki)
  • signal(chopstick(i1) 5)
  • think
  • while (1)

12
Potential Problems
  • Incorrect use of semaphores can lead to problems
  • Critical sections using semaphores must keep to
    a strict protocol
  • wait(S) critical section signal(S)
  • Problems
  • No mutual exclusion
  • Reverse signal(S) critical section wait(S)
  • Omit wait(S)
  • Deadlock
  • wait(S) critical section wait(S)
  • Omit signal(S)

13
Potential Solutions
  • How do we protect ourselves from these kinds of
    errors?
  • Develop language constructs that can be validated
    automatically by the compiler or run-time
    environment
  • Critical Regions
  • Monitors

14
Critical Regions
  • High-level synchronization construct
  • A shared variable v of type T, is declared as
  • v shared T
  • Variable v accessed only inside statement
  • region v when B do Swhere B is a Boolean
    expression.
  • While statement S is being executed, no other
    process can access variable v.

15
Critical Regions
  • Regions referring to the same shared variable
    exclude each other in time.
  • When a process tries to execute the region
    statement, the Boolean expression B is evaluated.
    If B is true, statement S is executed. If B is
    false, the process is delayed until B becomes
    true and no other process is in the region
    associated with v.

16
Critical Regions Bounded Buffer
  • struct buffer
  • int pooln
  • int count, in, out
  • Producer
  • region buffer when (count lt n)
  • poolin nextp
  • in (in1) n
  • count

Consumer region buffer when (count gt 0) nextc
poolout out (out1) n count--
17
Monitors
  • High-level synchronization construct that allows
    the safe sharing of an abstract data type among
    concurrent processes.
  • monitor monitor-name
  • shared variable declarations
  • procedure body P1 () . . .
  • procedure body P2 () . . .
  • procedure body Pn () . . .
  • initialization code

18
Schematic View of a Monitor
19
Monitors Condition Variables
  • To allow a process to wait within the monitor, a
    condition variable must be declared, as
  • condition x, y
  • Condition variable can only be used with the
    operations wait and signal.
  • The operation
  • x.wait()means that the process invoking this
    operation is suspended until another process
    invokes
  • x.signal()
  • The x.signal operation resumes exactly one
    suspended process. If no process is suspended,
    then the signal operation has no effect.

20
Monitors Condition Variables
  • If a task A within a monitor signals a suspended
    task B, there is an issue of who then gets to
    continue executing within the monitor.
  • Task A waits for B to leave the monitor or waits
    on another condition
  • Task B waits for A to leave the monitor or waits
    for another condition
  • A case can be made for either approach

21
Monitor With Condition Variables
22
Dining Philosophers Example
  • monitor dp
  • enum thinking, hungry, eating state5
  • condition self5
  • void pickup(int i)
  • void putdown(int i)
  • void test(int i)
  • void init()
  • for (int i 0 i lt 5 i)
  • statei thinking

23
Dining Philosophers
  • void pickup(int i)
  • statei hungry
  • test(i)
  • if (statei ! eating)
  • selfi.wait()
  • void putdown(int i)
  • statei thinking
  • // test left and right
  • test((i4) 5)
  • test((i1) 5)

void test(int i) if ( (state(i 4) 5 !
eating) (statei hungry)
(state(i 1) 5 ! eating)) statei
eating selfi.signal() Solution dp.pi
ckup(i) ... eat ... dp.putdown(i)
24
Monitor Implementation
  • Since only one task may be active in a monitor
    there must be a mutex protecting each method.
  • We also need to account for sending signals
    within a monitor that is, guard against having
    more than one active task within the monitor.
  • Our implementation uses semaphores for both
    mutual exclusion (initialized to 1 for a mutex)
    and counting the number of tasks waiting to be
    resumed within the monitor (initialized to 0
    counting semaphore)

25
Example Implementation
  • semaphore mutex // protect monitor
  • semaphore next // waiting to be resumed
  • int next_count 0
  • Each external method M will be replaced by
  • wait(mutex) // ensures mutual exclusion
  • body of M
  • if (next_count gt 0) // tasks waiting to be
    resumed
  • signal(next) // resume them
  • else
  • signal(mutex) // else unlock monitor
  • Mutual exclusion within a monitor is ensured.

26
Example Implementation CV
  • Implement so that the signaling task waits to
    complete
  • For each condition variable cv, we have
  • semaphore cv_sem // (initially 0)
  • int cv_count 0

cv.signal if (cv_count gt 0) next-count
signal(cv_sem) wait(next) next-count--
cv.wait cv_count if (next_count gt
0) signal(next) else signal(mutex) wait(c
v_sem) cv_count--
27
More on Monitor Implementations
  • How can we control the task resumption order?
  • Conditional-wait construct x.wait(c)
  • c integer expression evaluated when wait
    executed.
  • value of c (a priority number) stored with the
    name of the process that is suspended.
  • when x.signal is executed, process with smallest
    associated priority number is resumed next.
  • Verifying correctness Check two conditions
  • User processes must always make their calls on
    the monitor in a correct sequence.
  • Must ensure that an uncooperative process does
    not ignore the mutual-exclusion gateway provided
    by the monitor, and try to access the shared
    resource directly, without using the access
    protocols.

28
OS Synchronization
  • spin locks (simple mutex),
  • blocking locks (mutex)
  • adaptive mutex
  • condition variables

29
Spin Locks or Simple Mutexes
  • The idea is to provide a basic, HW supported
    primitive with low overhead.
  • Lock held for short periods of time
  • If locked, then busy-wait on the resource
  • Must not give up processor! In other words, can
    not block.

30
Spin-Lock implementation
void spin_lock (spinlock_t s) while
(test_and_set (s) ! 0) while (s ! 0)
void spin_unlock (spinlock_t s) s 0
31
Blocking Locks/Mutex
  • Allows threads to block
  • Interface
  • lock(), unlock () and trylock ()
  • Consider traditional kernel locked flag
  • Mutex allows for exclusive access to flag,
    solving the race condition
  • flag can be protected by a spin lock.

32
Condition variables
  • Associated with a predicate which is protected by
    a mutex (usually a spin lock).
  • Useful for event notification
  • Can wakeup one or all sleeping threads!

33
Condition Variables
  • Up to 3 or more mutex are typically required
  • one for the predicate
  • one for the sleep queue (or CV list)
  • one or more for the scheduler queue (swtch ())
  • deadlock avoided by requiring a strict order

34
Condition Variables
update predicate
wake up one thread
Thread sets event
35
CV Implementation
Void do_signal (cv c) lock (cv-gtlistlock)
-- remove 1 thread -- unlock
(cv-gtlistlock) if thread, make runnable
return void do_broadcast (cv c) lock
(cv-gtlistlock) while (list is nonempty)
remove a thread make it runnable unlock
(cv-gtlistlock) return
wait() called with mutex s already locked. Void
wait (cv c, mutex_t s) lock
(cv-gtlistlock) -- add thread to queue --
unlock (cv-gtlistlock) unlock (s) swtch
() / return gt after wakup / lock (s)
return
36
Solaris 2 Synchronization
  • Implements a variety of locks to support
    multitasking, multithreading (including real-time
    threads), and multiprocessing.
  • Uses adaptive mutexes for efficiency when
    protecting data from short code segments.
  • Uses condition variables and readers-writers
    locks when longer sections of code need access to
    data.
  • Uses turnstiles to order the list of threads
    waiting to acquire either an adaptive mutex or
    reader-writer lock.

37
Windows 2000 Synchronization
  • Uses interrupt masks to protect access to global
    resources on uniprocessor systems.
  • Uses spinlocks on multiprocessor systems.
  • Also provides dispatcher objects which are used
    by user space threads and act as either mutexes,
    semaphores or events.
  • An event acts much like a condition variable.
  • signaled or unsignaled state
Write a Comment
User Comments (0)
About PowerShow.com