Chapter 6: Process Synchronization - PowerPoint PPT Presentation

1 / 54
About This Presentation

Chapter 6: Process Synchronization


Title: Module 7: Process Synchronization Author: Marilyn Turnamian Last modified by: Yohanes Stefanus Created Date: 7/23/1999 1:31:00 PM Document presentation format – PowerPoint PPT presentation

Number of Views:48
Avg rating:3.0/5.0
Slides: 55
Provided by: Marily438


Transcript and Presenter's Notes

Title: Chapter 6: Process Synchronization

Chapter 6 Process Synchronization
  • Concurrent access to shared data by many
    cooperating processes may result in data
  • Maintaining data consistency requires mechanisms
    to ensure the orderly execution of cooperating
  • Suppose that we wanted to provide a solution to
    the consumer-producer problem that fills all the
    buffers. We can do so by having an integer
    counter that keeps track of the number of full
    buffers. Initially, counter is set to 0. It is
    incremented by the producer after it produces a
    new item and is decremented by the consumer after
    it consumes an item.

  • Shared data
  • define BUFFER_SIZE 999
  • typedef struct
  • . . .
  • item
  • item bufferBUFFER_SIZE
  • int in 0
  • int out 0
  • int counter 0

  • Producer process
  • item nextProducedwhile (TRUE)
  • / produce an item in nextProduced
  • while (counter BUFFER_SIZE)
  • / do nothing /
  • bufferin nextProduced
  • in (in 1) BUFFER_SIZE
  • counter

  • Consumer process
  • item nextConsumed
  • while (TRUE)
  • while (counter 0)
  • / do nothing /
  • nextConsumed bufferout
  • out (out 1) BUFFER_SIZE
  • counter--
  • / consume the item in
    nextConsumed /

Bounded Buffer
  • Each of the statementscountercounter--mus
    t be performed atomically.
  • Atomic operation means an operation that
    completes in its entirety without interruption.

Bounded Buffer
  • The statement counter may be implemented in
    machine language asregister1 counter
  • register1 register1 1counter register1
  • The statement counter-- may be implemented
    asregister2 counterregister2 register2
    1counter register2

Bounded Buffer
  • If both the producer and consumer attempt to
    update the buffer concurrently, the assembly
    language statements may get interleaved.
  • Interleaving depends upon how the producer and
    consumer processes are scheduled.

Bounded Buffer
  • Assume counter is initially 5. One interleaving
    of statements isproducer register1 counter
    (register1 5)producer register1 register1
    1 (register1 6)consumer register2 counter
    (register2 5)consumer register2 register2
    1 (register2 4)producer counter register1
    (counter 6)consumer counter register2
    (counter 4)
  • The value of counter may be either 4, 5 or 6,
    where the correct result should be 5.

Race Condition
  • Race condition The situation where several
    processes access and manipulate shared data
    concurrently. The final value of the shared data
    depends upon which process finishes last.
  • To prevent race conditions, concurrent processes
    must be synchronized.

The Critical-Section Problem
  • n processes all competing to use some shared data
  • Each process has a code segment, called critical
    section, in which the shared data is accessed.
  • Problem ensure that when one process is
    executing in its critical section, no other
    process is allowed to execute in its critical

Requirements for a Solution to the
Critical-Section Problem
  • 1. Mutual Exclusion. If process Pi is executing
    in its critical section, then no other processes
    can be executing in their critical sections.
  • 2. Progress. If no process is executing in its
    critical section and there exist some processes
    that wish to enter their critical sections, then
    only those processes that are not executing in
    their remainder section can participate in the
    decision on which process will enter its critical
    section next, and this selection cannot be
    postponed indefinitely.
  • 3. Bounded Waiting. A bound must exist on the
    number of times that other processes are allowed
    to enter their critical sections after a process
    has made a request to enter its critical section
    and before that request is granted.

  • Assume that each process executes at a nonzero
  • No assumption concerning relative speed of the n

Initial Attempts to Solve Problem
  • Only 2 processes, P0 and P1
  • General structure of process Pi (other process
  • do
  • entry section
  • critical section
  • exit section
  • remainder section
  • while (TRUE)
  • i 1 - j.
  • Processes may share some common variables to
    synchronize their actions.

Algorithm 1
  • Shared variables
  • int turninitially turn 0
  • turn i ? Pi can enter its critical section
  • Process Pi
  • do
  • while (turn ! i)
  • critical section
  • turn j
  • remainder section
  • while (TRUE)
  • Satisfies mutual exclusion, but not progress

Algorithm 2
  • Shared variables
  • boolean flag2initially flag 0 flag 1
  • flag i TRUE ? Pi ready to enter its critical
  • Process Pi
  • do
  • flagi TRUE while (flag j )
    critical section
  • flag i FALSE
  • remainder section
  • while (TRUE)
  • Satisfies mutual exclusion, but not progress

Algorithm 3 (Petersons)
  • Combined shared variables of algorithms 1 and 2.
  • Initially, flag0 flag1 FALSE, and the
    value of turn is either 0 or 1.
  • Process Pi
  • do
  • flag i TRUE turn j while (flag j
    and turn j)
  • critical section
  • flag i FALSE
  • remainder section
  • while (TRUE)
  • Meets all three requirements solves the
    critical-section problem for two processes.

Synchronization Hardware
  • Hardware features can make the programming task
    easier and improve system efficiency.
  • Help solving the critical-section problem.
  • The critical-section problem could be solved
    simply in a uniprocessor environment if we could
    forbid interrupts to occur while a shared
    variable is being modified.
  • Many machines provide special hardware
    instructions that allow us either to test and
    modify the content of a word atomically, or to
    swap the contents of two words atomically.
  • Atomically uninterruptible.

TestAndSet instruction
  • Test and modify the content of a word atomically
  • boolean TestAndSet(boolean target)
  • boolean rv target
  • target TRUE
  • return rv

Mutual Exclusion with Test-and-Set
  • Shared data boolean lock FALSE
  • Process Pi
  • do
  • while (TestAndSet(lock))
  • critical section
  • lock FALSE
  • remainder section
  • while (TRUE)

Swap Instruction
  • Atomically swap two variables.
  • void Swap(boolean a, boolean b)
  • boolean temp a
  • a b
  • b temp

Mutual Exclusion with Swap
  • Shared data (initialized to FALSE) boolean
  • Each process has a local boolean variable key
  • Process Pi
  • do
  • key TRUE
  • while (key TRUE)
  • Swap(lock,key)
  • critical section
  • lock FALSE
  • remainder section
  • while (TRUE)

  • Synchronization tool that can be used to solve
    complex problems
  • A semaphore S is an integer variable that
  • can only be accessed via two indivisible
    (atomic) operations
  • wait (S)
  • while S? 0 do no-op S--
  • signal (S)
  • S
  • These two semaphore operations are also called P
    and V, respectively.
  • P proberen ( to test), V verhogen ( to
    increment) in Dutch.

Critical Section of n Processes
  • Shared data
  • semaphore mutex //initially mutex 1
  • Process Pi do P(mutex) critical
  • V(mutex) remainder section while

  • Semaphore implemented using busy-waiting is
    called a spinlock, because the process spins
    while waiting for the the lock.
  • Busy waiting wastes CPU cycles that some other
    process might be able to use productively.
  • The advantage of a spinlock is that no context
    switch is required when a process must wait on a
    lock. Spinlocks are useful in multiprocessor

Semaphore Implementation
  • To avoid busy-waiting, when a process executes
    the P operation and finds that the semaphore
    value is not positive, the process blocks itself.
  • The block operation places the process into a
    waiting queue associated with the semaphore, and
    the state of the process is switched to the
    waiting state. Then, control is transferred to
    the CPU scheduler, which selects another process
    to run.
  • A process that is blocked, waiting on a
    semaphore, should be restarted when some other
    process executes the V operation. The process is
    restarted by a wakeup operation, which changes
    the process from the waiting state to the ready
    state. The process is then placed in the ready

Semaphore Implementation
  • Define a semaphore as a record
  • typedef struct
  • int value struct process L
  • Assume two simple operations
  • block suspends the process that invokes it.
  • wakeup(P) resumes the execution of a blocked
    process P.

  • Semaphore operations now defined as
  • P(S) S.value--
  • if (S.value lt 0)
  • add this process to S.L block
  • V(S) S.value
  • if (S.value lt 0)
  • remove a process P from S.L wakeup(P)

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

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.

Two Types of Semaphores
  • Counting semaphore integer value can range over
    an unrestricted domain.
  • Binary semaphore integer value can range only
    between 0 and 1 can be simpler to implement.

Classical Problems of Synchronization
  • Bounded-Buffer Problem
  • Readers and Writers Problem
  • Dining-Philosophers Problem

Bounded-Buffer Problem
  • Shared datasemaphore full, empty,
    mutexInitiallyfull 0, empty n, mutex
  • The mutex semaphore provides mutual exclusion for
    accesses to the buffer pool.
  • The empty semaphore and full semaphore count the
    number of empty and full buffers, respectively.

Bounded-Buffer Problem Producer Process
  • do
  • produce an item in nextp
  • P(empty)
  • P(mutex)
  • add nextp to buffer
  • V(mutex)
  • V(full)
  • while (TRUE)

Bounded-Buffer Problem Consumer Process
  • do
  • P(full)
  • P(mutex)
  • remove an item from buffer to nextc
  • V(mutex)
  • V(empty)
  • consume the item in nextc
  • while (TRUE)

Readers-Writers Problem
  • The writers have exclusive access to the shared
  • First version no reader will be kept waiting
    unless a writer has already obtained permission
    to use the shared object.
  • Writers may starve.
  • Shared datasemaphore mutex 1, wrt 1
  • int readcount 0

Readers-Writers Problem Writer Process
  • P(wrt)
  • writing is performed
  • V(wrt)

Readers-Writers Problem Reader Process
  • P(mutex)
  • readcount
  • if (readcount 1)
  • P(wrt)
  • V(mutex)
  • reading is performed
  • P(mutex)
  • readcount--
  • if (readcount 0)
  • V(wrt)
  • V(mutex)

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

Dining-Philosophers Problem
  • Philosopher i
  • do
  • P(chopsticki)
  • P(chopstick(i1) 5)
  • eat
  • V(chopsticki)
  • V(chopstick(i1) 5)
  • think
  • while (TRUE)
  • This solution might create a deadlock.

Dining-Philosophers Problem
  • It is a simple representation of an important
    concurrency-control problem where there is the
    need to allocate several resources among several
    processes in a deadlock-free and starvation-free

  • High-level synchronization construct that allows
    the safe sharing of an abstract data type among
    concurrent processes.
  • monitor monitor-name
  • shared variable declarations
  • procedure P1 ()
  • . . .
  • procedure P2 ()
  • . . .
  • procedure Pn ()
  • . . .
  • initialization code

  • A monitor presents a set of programmer-defined
    operations (procedures) that are provided mutual
    exclusion within the monitor.
  • A monitor also contains the declaration of
    variables whose values define the state of an
    instance of that monitor.
  • The procedures operate on those variables.
  • A procedure defined within a monitor can access
    only those variables declared locally within the
    monitor and any formal parameters passed to the
  • Only one thread (or process) at a time can be
    active within the monitor.

  • To allow a process to wait within the monitor, a
    condition variable must be declared, such 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
  • x.signal()
  • The x.signal operation resumes exactly one
    suspended process. If no process is suspended,
    then the signal operation has no effect.

Schematic View of a Monitor
Monitor With Condition Variables
Signal-and-Wait or Signal-and-Continue?
  • Suppose that, when the x.signal() operation is
    invoked by a thread P, there is a suspended
    thread Q associated with condition x.
  • Two possibilities exist
  • 1. Signal-and-Wait P either waits until Q leaves
    the monitor, or waits for another condition.
  • 2. Signal-and-Continue Q either waits until P
    leaves the monitor, or waits for another

Dining Philosophers Example
  • A deadlock-free solution to the
    dining-philosophers problem
  • monitor diningPhilosophers
  • enum thinking, hungry, eating state5
  • condition self5
  • void pickup(int i) // following slides
  • void putdown(int i) // following slides
  • void test(int i) // following slides
  • void init()
  • for (int i 0 i lt 5 i)
  • statei thinking

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 neighbors
  • test((i4) 5)
  • test((i1) 5)

Dining Philosophers
  • void test(int i)
  • if ( (state(i 4) 5 ! eating)
  • (state i hungry)
  • (state(i 1) 5 ! eating))
  • state i eating
  • self i.signal()

Dining Philosophers
  • The distribution of the chopsticks is controlled
    by the monitor dp, which is an instance of the
    monitor type diningPhilosophers.
  • Philosopher i must invoke the operations pickup(
    ) and putdown( ) in the following sequence
  • dp.pickup(i)
  • eat()
  • dp.putdown(i)
  • Note that in this solution it is possible for a
    philosopher to starve to death.

Synchronization in Java
  • Java does not provide a semaphore, but we can
    easily construct one using Java synchronization
  • public class Semaphore
  • public Semaphore(int v) value v
  • public Semaphore() this(0)
  • public synchronized void P()
  • while (value lt 0)
  • try wait()
  • catch( InterruptedException ie )
  • value--
  • public synchronized void V()
  • value notify()
  • private int value

Synchronization in Java
  • Java synchronization uses an object's lock. This
    lock acts as a monitor.
  • Every Java object has an associated monitor.
  • However, Java does not provide support for named
    condition variables.
  • Each Java monitor has just one unnamed condition
    variable associated with it.
  • The wait(), notify(), and notifyAll() operations
    may apply to only this single condition variable.
  • When a Java thread is awakened via notify() or
    notifyAll(), it receives no information about why
    it was awakened. It is up to the thread to check
    for itself whether the condition for which is was
    waiting has been met.

  • Java monitors use the Signal-and-Continue
  • When a thread is signaled with the notify() or
    notifyAll() method, it can acquire the lock for
    the monitor only when the notifying thread exits
    the synchronized method or block.
Write a Comment
User Comments (0)