Title: Chapter%206:%20Synchronization
1Chapter 6 Synchronization
2Module 6 Synchronization
- 6.1 Background
- 6.2 The Critical-Section Problem
- 6.3 Petersons Solution
- 6.4 Synchronization Hardware
- 6.5 Semaphores
- 6.6 Classic Problems of Synchronization
- 6.7 Monitors
- 6.8 Synchronization Examples
- 6.9 Atomic Transactions
3Review 3.4.1 Interproces Communication
- Independent process cannot affect or be affected
by the execution of another process - Cooperating process can affect or be affected by
the execution of another process - Advantages of process cooperation
- Information sharing
- Computation speed-up
- Modularity
- Convenience
4Communications Models
Shared memory
Message passing
5Producer-Consumer Problem
- Paradigm for cooperating processes, producer
process produces information that is consumed by
a consumer process - unbounded-buffer places no practical limit on the
size of the buffer - bounded-buffer assumes that there is a fixed
buffer size
- Shared-Memory Solution Shared data
- define BUFFER_SIZE 10
- Typedef struct
- . . .
- item
- item bufferBUFFER_SIZE
- int in 0
- int out 0
6Bounded-Buffer Producer() Method
- while (true) / produce an item in
nextProduced/ - while (( (in 1) BUFFER_SIZE) out)
- / do nothing -- no free
buffers / - bufferin nextProduced
- in (in 1) BUFFER_SIZE
-
-
Solution is correct, but can only use
BUFFER_SIZE-1 elements
Bounded-Buffer Consumer() Method
while (true) while (in out)
// do nothing -- nothing to
consume nextConsumed bufferout
out (out 1) BUFFER SIZE / consume
the item in nextConsumed /
7BUFFER_SIZE solution
One more shared memory variable counter
8Still Have Problems
96.1 Background
- Concurrent access to shared data may result in
data inconsistency - Maintaining data consistency requires mechanisms
to ensure the orderly execution of cooperating
processes - Suppose that we wanted to provide a solution to
the consumer-producer problem (Section 3.4.1)
that fills all the buffers. We can do so by
having an integer count that keeps track of the
number of full buffers. Initially, count is set
to 0. It is incremented by the producer after it
produces a new buffer and is decremented by the
consumer after it consumes a buffer.
10Producer
- while (true)
- / produce an item and put in
nextProduced / - while (counter BUFFER_SIZE)
- // do nothing
- buffer in nextProduced
- in (in 1) BUFFER_SIZE
- counter
-
while (true) while (counter
0) // do nothing
nextConsumed bufferout out (out
1) BUFFER_SIZE counter-- /
consume the item in nextConsumed
Consumer
11Race Condition
- counter could be implemented as register1
counter register1 register1 1
counter register1 - counter-- could be implemented as register2
counter register2 register2 - 1
counter register2
12Race Condition
- Consider this execution interleaving with
counter 5 initially - T0 producer execute register1 counter
register1 5T1 producer execute register1
register1 1 register1 6 T2 consumer
execute register2 counter register2 5
T3 consumer execute register2 register2 - 1
register2 4 T4 producer execute counter
register1 count 6 T5 consumer execute
counter register2 count 4
If the order T4 and T5 is reversed, then the
final state is count 6
136.2 Solution to Critical-Section Problem
- Mutual Exclusion - If process Pi is executing in
its critical section, then no other processes can
be executing in their critical sections - Progress - If no process is executing in its
critical section and some processes wish to enter
their critical sections, then only those
processes that are not executing in their
remainder sections can participate in the
decision on 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 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
speed - No assumption concerning relative speed of the N
processes
146.2 Solution to Critical-Section Problem
- Example kernel data structure that is subject to
race conditions - List of open files in the OS
- Data structure for free/allocated memory
- Process lists
- Data structure for interrupts handling
- Approaches in handling critical sections in OS
- Preemptive kernels
- Nonpreemptive kernels
- A preemptive kernel is more suitable for
real-time programming, more responsive
?? p190 ??? 3 ?? 2 ?? ?? preemptive
156.3 Petersons Solution
- Two process solution
- Assume that the LOAD and STORE instructions are
atomic that is, cannot be interrupted. - The two processes share two variables
- int turn
- boolean flag2
- The variable turn indicates whose turn it is to
enter the critical section. - The flag array is used to indicate if a process
is ready to enter the critical section. flagi
true implies that process Pi is ready!
16Algorithm for Process Pi
- while (true)
- flagi TRUE
- turn j // j is i -1
- while ( flagj turn j)
- CRITICAL SECTION
- flagi FALSE
- REMAINDER SECTION
-
-
entry section (acquire lock)
exit section (release lock)
17- To prove Petersons solution is correct
- Mutual exclusion is preserved
- The progress requirement is satisfied
- The bounded-waiting requirement is met
186.4 Synchronization Hardware
- Many systems provide hardware support for
critical section code - Uniprocessors could disable interrupts
- Currently running code would execute without
preemption - Generally too inefficient on multiprocessor
systems - Operating systems using this not broadly scalable
- Modern machines provide special atomic hardware
instructions - Atomic non-interruptable
- Either test memory word and set value
- Or swap contents of two memory words
19TestAndndSet Instruction
- Shared boolean variable lock initialized to
false. - Solution using TestandSet
- while (true)
- while ( TestAndSet (lock ))
- // do nothing
- // critical section
- lock FALSE
- // remainder section
-
-
- Definition
- boolean TestAndSet (boolean target)
-
- boolean rv target
- target TRUE
- return rv
-
20Swap Instruction
- Shared boolean variable lock initialized to
FALSE Each process has a local boolean variable
key. - Solution using Swap
- while (true)
- key TRUE
- while ( key TRUE)
- Swap (lock, key )
-
- // critical section
- lock FALSE
- // remainder section
-
-
- Definition
- void Swap (boolean a, boolean b)
-
- boolean temp a
- a b
- b temp
-
Does not satisfy bounded-waiting
21Bounded-waiting mutual exclusion with TestAndSet()
- Common data structure boolean waitingn and
boolean lock - Solution using TestandSet
- while (true)
- waitingi TRUE
- key TRUE
- while ( waitingi key)
- key
TestAndSet(lock) - waitingi FALSE
- // critical section
- j (i1) n
- while ( ( j ! i)
!waitingj ) - j (j 1) n
- if (j i)
- lock FALSE
- else
- waitingj FALSE
- // remainder section
-