Chapter 7: Process Synchronization - PowerPoint PPT Presentation

About This Presentation
Title:

Chapter 7: Process Synchronization

Description:

Chapter 7: Process Synchronization Contents Background The Critical-Section Problem Synchronization Hardware Semaphores Classical Problems of Synchronization Monitors ... – PowerPoint PPT presentation

Number of Views:235
Avg rating:3.0/5.0
Slides: 117
Provided by: AyHw
Category:

less

Transcript and Presenter's Notes

Title: Chapter 7: Process Synchronization


1
Chapter 7 Process Synchronization
2
Contents
  • Background
  • The Critical-Section Problem
  • Synchronization Hardware
  • Semaphores
  • Classical Problems of Synchronization
  • Monitors
  • Java Synchronization
  • Synchronization in Solaris 2
  • Synchronization in Windows NT

3
Background
7.1
  • Concurrent access to shared data may result in
    data inconsistency.
  • Maintaining data consistency requires mechanisms
    to ensure the orderly execution of cooperating
    processes.
  • Shared-memory solution to bounded-butter problem
    (Chapter 4) has a race condition on the class
    data count

4
Bounded Buffer
  • public class BoundedBuffer
  • public void enter(Object item)
  • // producer calls this method
  • public Object remove()
  • // consumer calls this method
  • // potential race condition on count
  • private volatile int count

5
enter() Method
  • // producer calls this method
  • public void enter(Object item)
  • while (count BUFFER_SIZE)
  • // do nothing
  • // add an item to the buffer
  • count
  • bufferin item
  • in (in 1) BUFFER_SIZE

6
remove() Method
  • // consumer calls this method
  • public Object remove()
  • Object item
  • while (count 0)
  • // do nothing
  • // remove an item from the buffer
  • --count
  • item bufferout
  • out (out 1) BUFFER_SIZE
  • return item

7
In machine language
  • count register1 count register1 register1
    1 count register1
  • --count register2 count register2 register2
    1 count register2
  • The concurrent execution of the statements
    count and count is equivalent to a sequential
    execution where the lower-level statements are
    interleaved in some arbitrary order.

8
Race Condition
  • T0 producer execute rigister1 count
    register15
  • T1 producer execute rigister1 rigister1
    1 register16
  • T2 consumer execute rigister2 count
    register25
  • T3 consumer execute rigister2 rigister2
    1 register24
  • T4 producer execute count rigister1 count
    6
  • T5 consumer execute count rigister2 count
    4

Should be 5. Error!
To guard against the race condition, we need to
ensure that only one thread at a time can be
manipulating the variable count. To make such a
guarantee, we require some form of
synchronization of the threads.
9
Critical-Section Problem
7.2
  • Each thread has a segment of code, called a
    critical section, in which the thread may be
    changing common variables, updating a table,
    writing a file, and so on.
  • When one thread is executing in its critical
    section, no other thread is to be allowed to
    execute in its critical sectionmutually
    exclusive.
  • The critical-section problem is how to choose a
    protocol that the threads can use to cooperate.

10
Critical-Section Problem
7.2
  • Each thread has a segment of code, called a
    critical section, in which the thread may be
    changing common variables, updating a table,
    writing a file, and so on.
  • When one thread is executing in its critical
    section, no other thread is to be allowed to
    execute in its critical sectionmutually
    exclusive.
  • The critical-section problem is how to choose a
    protocol that the threads can use to cooperate.

( ) When one thread is executing in its
critical section, no other thread is to be
allowed to execute in its critical section, this
is called _________. (A) global data (B) common
method (C) mutually exclusive (D) constant
accessing (E) value assertion
Answer C
11
Critical-Section Problem
  • 1. Mutual Exclusion. If thread Ti is executing
    in its critical section, then no other threads
    can be executing in their critical sections.
  • 2. Progress. If no thread is executing in its
    critical section and there exist some threads
    that wish to enter their critical sections, then
    only those threads that are not executing in
    their noncritical section can participate in the
    decision of which 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 threads 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. This bound
    prevents starvation of any single thread.

12
Critical-Section Problem
  • 1. Mutual Exclusion. If thread Ti is executing
    in its critical section, then no other threads
    can be executing in their critical sections.
  • 2. Progress. If no thread is executing in its
    critical section and there exist some threads
    that wish to enter their critical sections, then
    only those threads that are not executing in
    their noncritical section can participate in the
    decision of which 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 threads 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. This bound
    prevents starvation of any single thread.

Short Answer Question A solution to the
critical-section problem must satisfy three
requirements mutual exclusive, progress, and
bounded waiting. Please explain the meaning of
these requirements.
13
Critical-Section Problem
  • 1. Mutual Exclusion. If thread Ti is executing
    in its critical section, then no other threads
    can be executing in their critical sections.
  • 2. Progress. If no thread is executing in its
    critical section and there exist some threads
    that wish to enter their critical sections, then
    only those threads that are not executing in
    their noncritical section can participate in the
    decision of which 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 threads 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. This bound
    prevents starvation of any single thread.

Multiple Choice Question ( ) Which of the
following is not one of the requirements for a
solution of critical-section problem? (A)
progress (B) loopless (C) mutual exclusive (D)
bounded waiting
Answer B
14
Critical-Section Problem
  • We can make no assumption concerning the
    relative speed of the n threads.
  • The solutions should not rely on any assumptions
    concerning the hardware instructions.
  • However, the basic machine-language instructions
    (the primitive instructions such as load, store,
    and test) are executed atomically.

15
Critical-Section Problem
  • We can make no assumption concerning the
    relative speed of the n threads.
  • The solutions should not rely on any assumptions
    concerning the hardware instructions.
  • However, the basic machine-language instructions
    (the primitive instructions such as load, store,
    and test) are executed atomically.

True-False Question ( ) When solving critical
section problems, we should make proper
assumption concerning the relative speed of the
threads.
Answer
16
Two-Tasks Solutions
7.3
  • Each thread is implemented using the worker
    class. (Fig 7.1)
  • A call to the methods criticalSection() and
    nonCriticalSection() represents the places where
    each thread performs its critical and noncritical
    sections.
  • Prior to calling its critical section, each
    thread will call the method enteringCriticalSectio
    n().
  • A thread will not return from enteringCriticalSect
    ion() until it is able to enter its critical
    section.

17
Worker Thread
  • public class Worker extends Thread
  • public Worker(String n, int i, MutualExclusion
    s)
  • name n
  • id i
  • shared s
  • public void run() / see next slide /
  • private String name
  • private int id
  • private MutualExclusion shared

18
run() Method of Worker Thread
Codes in critical section
  • public void run()
  • while (true)
  • shared.enteringCriticalSection(id)
  • system.out.println(name is in critical
    section)
  • MutualExclusion.criticalSection()
  • shared.leavingCriticalSection(id)
  • System.out.println(name is out of critical
    section)
  • MutualExclusion.noncriticalSection()

Codes out of critical section
19
MutualExclusion Abstract Class
This abstract class will serve as a template for
the following three algorithms
  • public abstract class MutualExclusion
  • public static void criticalSection()
  • // simulate the critical section
  • public static void nonCriticalSection()
  • // simulate the non-critical section
  • public abstract void enteringCriticalSection(int
    t)
  • public abstract void leavingCriticalSection(int
    t)
  • public static final int TURN_0 0
  • public static final int TURN_1 1

20
Testing Each Algorithm
  • public class TestAlgorithm
  • public static void main(String args)
  • MutualExclusion alg new Algorithm_1()
  • Worker first new Worker("Runner 0", 0,
    alg)
  • Worker second new Worker("Runner 1", 1,
    alg)
  • first.start()
  • second.start()

Creating the two threads and used to test each
algorithm
21
Algorithm 1
7.3.1
Keeps the thread in the Runnable state, but also
allows the JVM to select another Runnable thread
of equal priority to run.
  • public class Algorithm_1 extends MutualExclusion
  • public Algorithm_1()
  • turn TURN_0
  • public void enteringCriticalSection(int t)
  • while (turn ! t)
  • Thread.yield()
  • public void leavingCriticalSection(int t)
  • turn 1 - t
  • private volatile int turn

22
Algorithm 1
  • Ensures that only one thread at a time can be in
    its critical section.
  • However, does not satisfy the progress
    requirement, since it requires strict alternation
    of threads in the execution of their critical
    section.

23
Algorithm 2
  • public class Algorithm_2 extends MutualExclusion
  • public Algorithm_2()
  • flag0 false
  • flag1 false
  • public void enteringCriticalSection(int t)
  • int other 1 - t
  • flagt true
  • while (flagother true)
  • Thread.yield()
  • public void leavingCriticalSection(int t)
  • flagt false
  • private volatile boolean flag new
    boolean2

24
Algorithm 2
  • public class Algorithm_2 extends MutualExclusion
  • public Algorithm_2()
  • flag0 false
  • flag1 false
  • public void enteringCriticalSection(int t)
  • int other 1 - t
  • flagt true
  • while (flagother true)
  • Thread.yield()
  • public void leavingCriticalSection(int t)
  • flagt false
  • private volatile boolean flag new
    boolean2

Short Answer Question Examine the
algorithm on the right for solving two-tasks
critical-section problem. What this algorithm has
achieved and what kind of problem this algorithm
is encountered, if any ?
25
Algorithm 2
  • The mutual-exclusion requirement is satisfied.
  • Unfortunately, the progress requirement is still
    not met.
  • When both threads perform the while statement,
    they will loop forever as the value of flag for
    the other thread is true.

26
Algorithm 3
  • public class Algorithm_3 extends MutualExclusion
  • public Algorithm_3()
  • flag0 false
  • flag1 false
  • turn TURN_0
  • public void enteringCriticalSection(int t) /
    see next slides /
  • public void leavingCriticalSection(int t)
    / see next slides /
  • private volatile int turn
  • private volatile boolean flag new
    boolean2

27
Algorithm 3
  • public void enteringCriticalSection(int t)
  • int other 1 - t
  • flagt true
  • turn other
  • while ( (flagother true) (turn other)
    )
  • Thread.yield()
  • public void leavingCriticalSection(int t)
    flagt false

28
Algorithm 3
  • Correct solution to the critical-section problem.
  • If both threads try to enter at the same time,
    turn is set to both I and j at roughly the same
    time.
  • Only one of these assignments lasts the other
    will occur, but will be overwritten immediately.
  • The eventual value of turn decides which of the
    two threads is allowed to enter its critical
    section first.

29
Synchronization Hardware
7.4
  • Hardware instructions can be used effectively in
    solving critical-section problem.
  • It allows as either to test and modify the
    content of a word, or to swap the contents of two
    words, atomically --- as one uninterruptible unit.

30
Synchronization Hardware
  • public class HardwareData
  • public HardwareData(boolean v)
  • data v
  • public boolean get()
  • return data
  • public void set(boolean v)
  • data v
  • private boolean data

31
Test-and-Set Instruction (in Java)
  • public class HardwareSolution
  • public static boolean testAndSet(HardwareData
    target)
  • HardwareData temp new HardwareData(target.get(
    ))
  • target.set(true)
  • return temp.get()

32
Test-and-Set Instruction (in Java)
True-False Question ( ) The value of the lock
returned by the test-and set instruction is the
value after the instruction is applied onto the
lock.
  • public class HardwareSolution
  • public static boolean testAndSet(HardwareData
    target)
  • HardwareData temp new HardwareData(target.get(
    ))
  • target.set(true)
  • return temp.get()

Answer
33
Thread using Test-and-Set
  • HardwareData lock new HardwareData(false)
  • while (true)
  • while (HardwareSolution.testAndSet(lock))
  • Thread.yield( ) // do nothing
  • criticalSection( )
  • lock.set(false)
  • nonCriticalSection( )

34
Thread using Test-and-Set
Multiple Choices Question ( ) When calling a
test-and-set instruction, a ______ must be
provided as its parameter.(a) semaphore (b)
integer (c) constant (d) lock
  • HardwareData lock new HardwareData(false)
  • while (true)
  • while (HardwareSolution.testAndSet(lock))
  • Thread.yield( ) // do nothing
  • criticalSection( )
  • lock.set(false)
  • nonCriticalSection( )

Answer d
35
Thread using Test-and-Set
True-False Question ( ) When the value
returned by the test-and-set instruction is
false, it means that the locking is not
successful.
  • HardwareData lock new HardwareData(false)
  • while (true)
  • while (HardwareSolution.testAndSet(lock))
  • Thread.yield( ) // do nothing
  • criticalSection( )
  • lock.set(false)
  • nonCriticalSection( )

Answer x
36
Swap instruction
  • Also executed atomically.
  • public static void swap(HardwareData a,
    HardwareData b)
  • HardwareData temp new HardwareData(a.get())
  • a.set(b.get())
  • b.set(temp.get())

37
Thread using Swap
  • HardwareData lock new HardwareData(false)
  • HardwareData key new HardwareData(true)
  • while (true)
  • key.set(true)
  • do
  • HardwareSolution.swap(lock,key)
  • while (key.get() true)
  • criticalSection( )
  • lock.set(false)
  • nonCriticalSection( )

38
Thread using Swap
Multiple Choices Question ( ) The value of
the key used to switch with the lock must be set
to ______ before calling the swap method.(a)
constant (b) false (c) true (d) integer
  • HardwareData lock new HardwareData(false)
  • HardwareData key new HardwareData(true)
  • while (true)
  • key.set(true)
  • do
  • HardwareSolution.swap(lock,key)
  • while (key.get() true)
  • criticalSection( )
  • lock.set(false)
  • nonCriticalSection( )

Answer c
39
Semaphore
7.5
  • Previous solutions (7.3) are not easy to
    generalize to more complex problems.
  • Semaphores can be implemented as synchronization
    tool that does not require busy waiting.
  • A semaphore S is an integer variable that can
    only be accessed via two indivisible (atomic)
    operations P and V.
  • P(S)
  • while S ? 0
  • // no-op S--

These are classical definition of P and V, they
require busy waiting.
V(S) S
40
Semaphore as General Synchronization Tool
7.5.1
  • Semaphore S // initialized to 1
  • P(S)
  • CriticalSection()
  • V(S)
  • The value of a counting semaphore can range over
    an unrestricted domain. The value of a binary
    semaphore can range only between 0 and 1.

41
Semaphore Eliminating Busy-Waiting
  • The main disadvantage of previous solutions they
    all require busy waitinga problem in single CPU,
    multiprogramming system.
  • Busy waiting wastes CPU cycles that some other
    process might be able to use productively. This
    type of semaphore is also called a spinlock.
  • Spinlocks are useful in multiprocessor systems.
    The
  • advantage of a spinlock is that no context
    switch is required
  • when a process must wait on a lock (context
    switch
  • may take considerable time).
  • Spinlocks are useful when locks are expected to
    be held for
  • short times.

42
Semaphore Eliminating Busy-Waiting
  • The main disadvantage of previous solutions they
    all require busy waitinga problem in single CPU,
    multiprogramming system.
  • Busy waiting wastes CPU cycles that some other
    process might be able to use productively. This
    type of semaphore is also called a spinlock.
  • To overcome the need for busy waiting, the
    definition of P and V are modified.

43
Semaphore Eliminating Busy-Waiting
Short Answer Question Although spinlocks
waist CPU time with busy waiting, they are still
useful in some systems. What are the advantage of
spinlocks and in which situation they are
considered useful?
  • The main disadvantage of previous solutions they
    all require busy waitinga problem in single CPU,
    multiprogramming system.
  • Busy waiting wastes CPU cycles that some other
    process might be able to use productively. This
    type of semaphore is also called a spinlock.
  • To overcome the need for busy waiting, the
    definition of P and V are modified.

44
Semaphore Eliminating Busy-Waiting
  • P(S)
  • value--
  • if (value lt 0)
  • add this process to list
  • block
  • V(S)
  • value
  • if (value lt 0)
  • remove a process P from list
  • wakeup(P)

The block operation places a process into a
waiting queue associated with the semaphore, and
the state of the process is switched to the
waiting state.
A process that is blocked, waiting on S, should
be restarted when some other process execute a V
operation.
When the process is restarted by the wakeup
operation, the process is changed from the
waiting state to the ready state.
45
Synchronization Using Semaphores
  • public class FirstSemaphore
  • public static void main(String args)
  • Semaphore sem new Semaphore(1)
  • Worker bees new Worker5
  • for (int i 0 i lt 5 i)
  • beesi new Worker(sem, "Worker "
  • (new Integer(i)).toString() )
  • for (int i 0 i lt 5 i)
  • beesi.start()

46
Worker Thread
  • public class Worker extends Thread
  • public Worker(Semaphore s, String n)
  • name n sem s
  • public void run()
  • while (true)
  • sem.P( )
  • // in critical section
  • sem.V( )
  • // out of critical section
  • private Semaphore sem
  • private String name

47
Deadlock and Starvation
the execution of a V operation
  • 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.

48
Deadlock and Starvation
the execution of a V operation
  • 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.

True-False Question ( ) A deadlock can only
happen in between two threads.
Answer
49
Classical Problems of Synchronization
7.6
  • Bounded-Buffer Problem
  • Readers and Writers Problem
  • Dining-Philosophers Problem

50
Bounded-Buffer Problem
7.6.1
  • public class BoundedBuffer
  • public BoundedBuffer() / see next slides /
  • public void enter() / see next slides /
  • public Object remove() / see next slides /
  • private static final int BUFFER_SIZE 2
  • private Semaphore mutex
  • private Semaphore empty
  • private Semaphore full
  • private int in, out
  • private Object buffer

51
Bounded Buffer Constructor
  • public BoundedBuffer()
  • // buffer is initially empty
  • count 0
  • in 0
  • out 0
  • buffer new ObjectBUFFER_SIZE
  • mutex new Semaphore(1)
  • empty new Semaphore(BUFFER_SIZE)
  • full new Semaphore(0)

52
enter() Method
  • public void enter(Object item)
  • empty.P()
  • mutex.P()
  • // add an item to the buffer
  • bufferin item
  • in (in 1) BUFFER_SIZE
  • mutex.V()
  • full.V()

53
enter() Method
Multiple Choices Question ( ) Consider
following program for the enter() method of
bounded-buffer problem. Which instruction is
missing from the blank?(a) empty.V() (b)
mutex.V() (c) full.P() (d) empty.P() public
void enter(Object item) empty.P()
mutex.P() // add an item to the buffer
bufferin item in (in 1)
BUFFER_SIZE __________ full.V()
  • public void enter(Object item)
  • empty.P()
  • mutex.P()
  • // add an item to the buffer
  • bufferin item
  • in (in 1) BUFFER_SIZE
  • mutex.V()
  • full.V()

Answer b
54
remove() Method
  • public Object remove()
  • full.P()
  • mutex.P()
  • // remove an item from the buffer
  • Object item bufferout
  • out (out 1) BUFFER_SIZE
  • mutex.V()
  • empty.V()
  • return item

55
Readers-Writers Problem
7.6.2
  • The readers-writers problem has several
    variations, all involving priorities.
  • first no reader will be kept waiting unless a
    writer has already obtained permission to use the
    shared database.

No reader should wait for other readers to finish
simply because a writer is waiting.
Starvation writers
56
Readers-Writers Problem
  • second once a writer is ready, that writer
    performs its write as soon as possible. If a
    writer is waiting to access the object, no new
    readers may start reading.

Starvation readers
  • Here we present the first solution.

57
Readers-Writers Problem
  • second once a writer is ready, that writer
    performs its write as soon as possible. If a
    writer is waiting to access the object, no new
    readers may start reading.

True-False Question ( ) If a reader will be
kept waiting only if a writer is currently
working on the database, the starvation may
happen on the reader.
Starvation readers
Answer
  • Here we present the first solution.

58
Readers-Writers Problem Reader
  • public class Reader extends Thread
  • public Reader(Database db)
  • server db
  • public void run()
  • int c
  • while (true)
  • c server.startRead()
  • // now reading the database
  • c server.endRead()
  • private Database server

59
Readers-Writers Problem Writer
  • public class Writer extends Thread
  • public Writer(Database db)
  • server db
  • public void run()
  • while (true)
  • server.startWrite()
  • // now writing the database
  • server.endWrite()
  • private Database server

60
Readers-Writers Problem (cont)
  • public class Database
  • public Database()
  • readerCount 0
  • mutex new Semaphore(1)
  • db new Semaphore(1)
  • public int startRead() / see next slides /
  • public int endRead() / see next slides /
  • public void startWrite() / see next slides /
  • public void endWrite() / see next slides
    /
  • private int readerCount // number of active
    readers
  • Semaphore mutex // controls access to
    readerCount
  • Semaphore db // controls access to
    the database

61
startRead() Method
  • public int startRead()
  • mutex.P()
  • readerCount
  • // if I am the first reader tell all others
  • // that the database is being read
  • if (readerCount 1)
  • db.P()
  • mutex.V()
  • return readerCount

62
endRead() Method
  • public int endRead()
  • mutex.P()
  • --readerCount
  • // if I am the last reader tell all others
  • // that the database is no longer being
    read
  • if (readerCount 0)
  • db.V()
  • mutex.V()
  • return readerCount

63
endRead() Method
  • public int endRead()
  • mutex.P()
  • --readerCount
  • // if I am the last reader tell all others
  • // that the database is no longer being
    read
  • if (readerCount 0)
  • db.V()
  • mutex.V()
  • return readerCount

True-False Question ( ) Although there are
many readers working on the database with the
startRead() and endRead() method, the semaphore
db will be acquired (P operation) and released (V
operation) by the same reader.
Answer
64
Writer Methods
  • public void startWrite()
  • db.P()
  • public void endWrite()
  • db.V()

65
Writer Methods
Short Answer Question Please explain
why the startWrite() method does not need to use
the semaphore mutex as startRead() does.
  • public void startWrite()
  • db.P()
  • public void endWrite()
  • db.V()

66
Dining-Philosophers Problem
7.6.3
  • A classic synchronization problem because it is
    an example of a large class of concurrency-control
    problems.

67
Dining-Philosophers Problem
  • Simple solution represent each chopstick by a
    semaphore. Get the chopstick PRelease the
    chopstick V
  • Shared data
  • Semaphore chopStick new
    Semaphore5

68
Dining-Philosophers Problem
  • Philosopher i
  • while (true)
  • // get left chopstick
  • chopSticki.P()
  • // get right chopstick
  • chopStick(i 1) 5.P()
  • eating()
  • //return left chopstick
  • chopSticki.V()
  • // return right chopstick
  • chopStick(i 1) 5.V()
  • thinking()

Deadlock when all five philosophers get her left
chopstick at the same time
69
Dining-Philosophers Problem
  • Philosopher i
  • while (true)
  • // get left chopstick
  • chopSticki.P()
  • // get right chopstick
  • chopStick(i 1) 5.P()
  • eating()
  • //return left chopstick
  • chopSticki.V()
  • // return right chopstick
  • chopStick(i 1) 5.V()
  • thinking()

Multiple Choices Question ( ) In
Dining-Philosophers Problem, if all philosophers
get their right chopstick at the same time, what
will happen?(a) starvation (b) deadlock (c)
blocking (d) synchronization (e) mutual
exclusioncc
Deadlock when all five philosophers get her left
chopstick at the same time
Answer b
70
Dining-Philosophers Problem
  • Preventing deadlock by placing restrictions
  • Allow at most four philosophers to be sitting
    simultaneously at the table.
  • Allow a philosopher to pick up only if both
    chopsticks are available.
  • Use an asymmetric solution(for example, an odd
    philosopher picks up left then right, whereas an
    even philosopher picks up her right chopstick and
    then her left.)
  • (Section 7.7 presents a solution to the
    dining-philosophers
    problem.)

71
Monitors
7.6.4
  • Although semaphores provide a convenient and
    effective mechanism for process synchronization,
    their incorrect use can still result in timing
    errors that are difficult to detect.
  • Examples

A process omits the mutex.P(), or the mutex.V(),
or both Either mutual exclusion is violated or
a deadlock will occur.
mutex.P() criticalSection() mutex.P() A
deadlock will occur.
mutex.V() criticalSection() mutex.P() Several
processes may be executing in their critical
section simultaneously.
72
Monitors
7.6.4
  • Although semaphores provide a convenient and
    effective mechanism for process synchronization,
    their incorrect use can still result in timing
    errors that are difficult to detect.
  • Examples

Multiple Choices Question ( ) What kind of
problem can happen if more than one thread work
on a semaphore in the following sequence?
mutex.V() criticalSection()
mutex.P()(a) starvation (b) deadlock (c)
blocking (d) not synchronizing (e) violate
mutual exclusion
A process omits the mutex.P(), or the mutex.V(),
or both Either mutual exclusion is violated or
a deadlock will occur.
mutex.P() criticalSection() mutex.P() A
deadlock will occur.
mutex.V() criticalSection() mutex.P() Several
processes may be executing in their critical
section simultaneously.
Answer e
73
Monitors
7.7
  • A monitor is a high-level abstraction that
    provides thread safety.
  • A monitor presents a set of programmer-defined
    operations that are provided mutual exclusion
    within the monitor.
  • Syntax of a monitor
  • monitor monitor-name
  • // variable declarations
  • public entry p1()
  • public entry p2()

74
Condition Variables
  • Encapsulation limits access to the local
    variables by only the local procedures.
  • The monitor construct prohibits concurrent access
    to all procedures defined within the monitor.
  • Only one thread may be active within the monitor
    at a time.
  • Synchronization is built into the monitor type,
    the programmer does not need to code it
    explicitly.
  • Special operations wait and signal can be invoked
    on the variables of type condition.
    condition x, y
  • A thread that invokes x.wait is suspended until
    another thread invokes x.signal

75
Condition Variables
  • Encapsulation limits access to the local
    variables by only the local procedures.
  • The monitor construct prohibits concurrent access
    to all procedures defined within the monitor.
  • Only one thread may be active within the monitor
    at a time.
  • Synchronization is built into the monitor type,
    the programmer does not need to code it
    explicitly.
  • Special operations wait and signal can be invoked
    on the variables of type condition.
    condition x, y
  • A thread that invokes x.wait is suspended until
    another thread invokes x.signal

True-False Question ( ) Although there maybe
several threads inside the monitor at the same
time, there can only be one thread with the state
of active at a time.
Answer ?
76
Monitor with condition variables
77
Solution to Dining Philosophers
With this, philosopher i can delay herself when
she is hungry, but is unable to obtain the
chopsticks she needs.
  • monitor diningPhilosophers
  • int state new int5
  • static final int THINKING 0
  • static final int HUNGRY 1
  • static final int EATING 2
  • condition self new condition5
  • public diningPhilosophers
  • for (int i 0 i lt 5 i)
  • statei THINKING
  • public entry pickUp(int i) / see next slides
    /
  • public entry putDown(int i) / see next slides
    /
  • private test(int i) / see next slides /

78
pickUp() Procedure
Each philosopher, before starting to eat, must
invoke the operation pickup().
  • public entry pickUp(int i)
  • statei HUNGRY
  • test(i)
  • if (statei ! EATING)
  • selfi.wait

May result in the suspension of the philosopher
thread.
79
test() Procedure
  • private test(int i)
  • if ( (state(i 4) 5 ! EATING)
  • (statei HUNGRY)
  • (state(i 1) 5 ! EATING) )
  • statei EATING
  • selfi.signal

Release selfi so that the thread can proceed.
80
putDown() Procedure
  • public entry putDown(int i)
  • statei THINKING
  • // test left and right neighbors
  • test((i 4) 5)
  • test((i 1) 5)

Ok, I have finished eating, now you guys go try
it!
81
Solution to Dining Philosophers
  • Sequence of invoke dp.pickUp(i) eat() dp.putD
    own(i)
  • This is a deadlock free solution but starvation
    is still possible.

82
Java Synchronization
7.8
  • An application that ensures data consistency even
    when being concurrently accessed by multiple
    threads is said to be thread safe.
  • In Section 7.5.2, using P and V semaphore
    operation for busy waiting was introduced. An
    alternative is allowing a process to block
    itself.

In Java, have a thread call the Thread.yield()
method can accomplish such blocking.
83
Busy Waiting
7.8.1.1
  • The yield() method makes more effective use of
    the CPU than busy waiting does.
  • However, using either busy waiting or yielding
    could potentially lead to a deadlock.
  • Example (Recall Section 7.3.1) (page 21 in this
    .ppt file)
  • JVM ensure higher priority thread in the
    Runnable state will run before lower priority
    one. If the producer has higher priority than
    consumer and the buffer is full the producer
    enter the while loop and wait (or yield) to
    another Runnable thread with equal priority while
    waiting for count to be decremented to less than
    BUFFER_SIZE. But the consumer has lower priority
    than producer and will never be scheduled by the
    JVM to run deadlocked.
  • The producer is waiting for the consumer to free
    buffer space and the consumer is waiting to be
    scheduled by the JVM.
  • We need a better solution.

84
Race Condition
  • Java prevent race condition by lock ownership.
  • Every object has a lock associated with it.
  • Calling a synchronized method requires owning
    the lock.
  • If a calling thread does not own the lock
    (another thread already owns it), the calling
    thread is placed in the entry set for the
    objects lock.
  • The entry set represents the set of threads
    waiting for the lock to become available.

85
Race Condition
  • Java prevent race condition by lock ownership.
  • Every object has a lock associated with it.
  • Calling a synchronized method requires owning
    the lock.
  • If a calling thread does not own the lock
    (another thread already owns it), the calling
    thread is placed in the entry set for the
    objects lock.
  • The entry set represents the set of threads
    waiting for the lock to become available.

Multiple Choices Question ( ) In Java, if a
calling thread cannot own a lock because another
thread already owns it, the calling thread is
placed in the _______ for the objects lock and
wait.(a) queue (b) wait array (c) monitor (d)
entry set (e) blocking room
Answer d
86
Entry Set
  • If the lock is available when a synchronized
    method is called, the calling thread becomes the
    owner of the objects lock and it can enter the
    method.
  • The lock is released when a thread exits the
    synchronized method.
  • If the entry set for the lock is not empty when
    the lock is released, the JVM selects an
    arbitrary thread from this set as the new owner
    of the lock.

87
Synchronized enter() Method
  • public synchronized void enter(Object item)
  • while (count BUFFER_SIZE)
  • Thread.yield()
  • count
  • bufferin item
  • in (in 1) BUFFER_SIZE

88
Synchronized remove() Method
  • public synchronized Object remove()
  • Object item
  • while (count 0)
  • Thread.yield()
  • --count
  • item bufferout
  • out (out 1) BUFFER_SIZE
  • return item

89
Wait set
  • synchronized method prevents race condition,
    however, the presence of yield() loop has led to
    another type of possible deadlock When the
    buffer is full and the consumer is sleeping, the
    producer calls the enter() method will own the
    lock and perform yield(). And, when the consumer
    awakens and tries to call the remove(), it will
    be blocked.
  • Wait set with wait() and notify() is introduced.

90
The wait() Method
  • When a thread calls wait(), the following occurs
  • - the thread releases the object lock.
  • - thread state is set to Blocked.
  • - thread is placed in the wait set for the
    object.

91
Entry and Wait Sets
92
The notify() Method
  • When a thread calls notify(), the following
    occurs
  • - Picks an arbitrary thread T from the wait set.
  • - Moves T to the entry set.
  • - Sets T from Blocked to Runnable.
  • T can now compete for the objects lock again.

93
enter() with wait/notify Methods
  • public synchronized void enter(Object item)
  • while (count BUFFER_SIZE)
  • try
  • wait()
  • catch (InterruptedException e)
  • count
  • bufferin item
  • in (in 1) BUFFER_SIZE
  • notify()

94
remove() with wait/notify Methods
  • public synchronized Object remove()
  • Object item
  • while (count 0)
  • try
  • wait()
  • catch (InterruptedException e)
  • --count
  • item bufferout
  • out (out 1) BUFFER_SIZE
  • notify()
  • return item

95
The Readers-Writers Problem--Solved with Java
Synchronization
7.8.3
  • public class Database
  • public Database()
  • readerCount 0
  • dbReading false
  • dbWriting false
  • public synchronized int startRead() / see
    next slides /
  • public synchronized int endRead() / see
    next slides /
  • public synchronized void startWrite() / see
    next slides /
  • public synchronized void endWrite() / see
    next slides /
  • private int readerCount
  • private boolean dbReading
  • private boolean dbWriting

96
startRead() Method
  • public synchronized int startRead()
  • while (dbWriting true)
  • try
  • wait()
  • catch (InterruptedException e)
  • readerCount
  • if (readerCount 1)
  • dbReading true
  • return readerCount

If I am the first reader tell all others that the
database is being read
97
endRead() Method
  • public synchronized int endRead()
  • --readerCount
  • if (readerCount 0)
  • db.notifyAll()
  • return readerCount

If I am the last reader tell all others that the
database is no longer being read
98
Writer Methods
  • public void startWrite()
  • while (dbReading true dbWriting
    true)
  • try
  • wait()
  • catch (InterruptedException e)
  • dbWriting true
  • public void endWrite()
  • dbWriting false
  • notifyAll()

Once there are either no readers or writers
indicate that the database is being written
99
Multiple Notifications
7.8.4
  • notify() selects an arbitrary thread from the
    wait set. This may not be the thread that you
    want to be selected.
  • Java does not allow you to specify the thread to
    be selected.
  • notifyAll() removes ALL threads from the wait set
    and places them in the entry set. This allows the
    threads to decide among themselves who should
    proceed next.
  • notifyAll() is a conservative strategy that works
    best when multiple threads may be in the wait set.

100
Block Synchronization
7.8.5
  • In Java, blocks of code rather than entire
    methods may be declared as synchronized. public
    void someMethod() synchronized(this) //
    remainder of the method
  • This yields a lock scope that is typically
    smaller than a synchronized method.
  • The amount of time between when a lock is
    assigned and when it is released is defined as
    the scope of the lock.

101
Block Synchronization
7.8.5
Multiple Choices Question ( )The amount of
time between when a lock is assigned and when it
is released is defined as the _______ of the
lock.(a) length (b) entry point (c) scope
(d) size (e) duration
  • In Java, blocks of code rather than entire
    methods may be declared as synchronized. public
    void someMethod() synchronized(this) //
    remainder of the method
  • This yields a lock scope that is typically
    smaller than a synchronized method.
  • The amount of time between when a lock is
    assigned and when it is released is defined as
    the scope of the lock.

Answer C
102
Block Synchronization
7.8.5
Multiple Choices Question ( ) In Java, the
scope of the lock can be defined within the size
of a(a) method (b) procedure (c) block (d)
message (e) entry set
  • In Java, blocks of code rather than entire
    methods may be declared as synchronized. public
    void someMethod() synchronized(this) //
    remainder of the method
  • This yields a lock scope that is typically
    smaller than a synchronized method.
  • The amount of time between when a lock is
    assigned and when it is released is defined as
    the scope of the lock.

Answer C
103
Block Synchronization (cont)
  • Object mutexLock new Object()
  • . . .
  • public void someMethod()
  • // non-critical section
  • synchronized(mutexLock)
  • try mutexLock.wait()
  • catch (InterruptedException ie)
  • synchronized(mutexLock)
  • mutexLock.notify()

104
Java Semaphores
7.8.6
  • Java does not provide a semaphore, but a basic
    semaphore can be constructed using Java
    synchronization mechanism.

105
Semaphore Class
  • public class Semaphore
  • public Semaphore()
  • value 0
  • public Semaphore(int v)
  • value v
  • public synchronized void P() / see next
    slide /
  • public synchronized void V() / see next slide
    /
  • private int value

106
P and V Operations
  • public synchronized void P()
  • while (value lt 0)
  • try
  • wait()
  • catch (InterruptedException e)
  • value --
  • public synchronized void V()
  • value
  • notify()

107
Synchronization Rules
7.8.7
  • A thread that owns the lock for an object can
    enter another synchronized method (or block) for
    the same object.
  • A thread can nest synchronized method invocations
    for different objects. Thus a thread can
    simultaneously own the lock for several different
    objects.
  • If a method is not declared as synchronized, then
    it can be invoked regardless of lock ownership,
    even while another synchronized method for the
    same object is executing.

108
Synchronization Rules
7.8.7
True-False Question ( ) Although a thread
cannot own many locks at the same time, it can
invoke many synchronized methods within a lock at
the same time.
  • A thread that owns the lock for an object can
    enter another synchronized method (or block) for
    the same object.
  • A thread can nest synchronized method invocations
    for different objects. Thus a thread can
    simultaneously own the lock for several different
    objects.
  • If a method is not declared as synchronized, then
    it can be invoked regardless of lock ownership,
    even while another synchronized method for the
    same object is executing.

Answer
109
Java Monitors (?)
7.8.8
110
OS Synchronization
7.9
  • Synchronization in Solaris 2 Provides
  • - adaptive mutex
  • - condition variables
  • - semaphores
  • - reader-writer locks

111
Adaptive Mutex
  • An adaptive mutex protects access to every
    critical data item. It starts as a standard
    semaphore implemented as a spinlock.
  • If the data are locked (in use), the adaptive
    mutex does one of two things
  • If the lock is held by a thread that is currently
    running on another CPU, the thread spins while
    waiting for the lock to become available.
  • If the thread holding the lock is not currently
    in run state, the thread blocks and go to sleep
    until the lock being released.

The thread holding the data is likely to end soon.
Put to sleep for avoiding the spinning when the
lock will not be freed reasonably quickly.
112
Adaptive Mutex
Multiple Choices Question ( ) Different
operations may be adopted by the adaptive mutex
mechanism when a thread is requesting a locked
data. The decision is made by the status of(a)
located memories (b) relative CPU speed (c) the
thread holding the lock (d) the type of
monitor entries
  • An adaptive mutex protects access to every
    critical data item. It starts as a standard
    semaphore implemented as a spinlock.
  • If the data are locked (in use), the adaptive
    mutex does one of two things
  • If the lock is held by a thread that is currently
    running on another CPU, the thread spins while
    waiting for the lock to become available.
  • If the thread holding the lock is not currently
    in run state, the thread blocks and go to sleep
    until the lock being released.

Put to sleep for avoiding the spinning when the
lcok will not be freed reasonably quickly.
Answer C
113
Adaptive Mutex
  • Adaptive mutex only protect those data that are
    accessed by short code segments where a lock will
    be held for less than a few hundred instructions.
  • For longer code segments, condition variables and
    semaphores are used.
  • If the desired lock is already held, the thread
    issues a wait and sleep.
  • The cost of putting a thread to sleep and waking
    it is less than the cost of wasting several
    hundred instructions waiting in a spinlock.

If the code segment is longer than that, spin
waiting will be exceedingly inefficient.
114
Readers-Writers Lock
  • The readers-writers locks are used to protect
    data that are accessed frequently, but usually
    only in a read-only manner.
  • In these circumstances, readers-writers locks are
    more efficient than semaphores.
  • Expensive to implement, so again they are used on
    only long sections of code.

THINK
115
Windows NT Synchronization
  • Windows NT Provides
  • - mutex
  • - critical sections
  • - semaphores
  • - event objects

116
The End
Write a Comment
User Comments (0)
About PowerShow.com