89
Silberschatz, Galvin and Gagne ©2013 perating System Concepts – 9 th Edition Chapter 5: Process Synchronization

Chapter 5: Process Synchronization

Embed Size (px)

DESCRIPTION

Chapter 5: Process Synchronization. Chapter 5: Process Synchronization. Background The Critical-Section Problem Peterson ’ s Solution Synchronization Hardware Mutex Locks Semaphores Classic Problems of Synchronization Monitors Synchronization Examples Alternative Approaches. - PowerPoint PPT Presentation

Citation preview

Page 1: Chapter 5:  Process Synchronization

Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Chapter 5: Process Synchronization

Page 2: Chapter 5:  Process Synchronization

5.2 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Chapter 5: Process Synchronization

Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Mutex Locks Semaphores Classic Problems of Synchronization Monitors Synchronization Examples Alternative Approaches

Page 3: Chapter 5:  Process Synchronization

5.3 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Objectives

To present the concept of process synchronization.

To introduce the critical-section problem, whose solutions can be used to ensure the consistency of shared data

To present both software and hardware solutions of the critical-section problem

To examine several classical process-synchronization problems

To explore several tools that are used to solve process synchronization problems

Page 4: Chapter 5:  Process Synchronization

5.4 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Background

Processes can execute concurrently

May be interrupted at any time, partially completing execution

Concurrent access to shared data may result in data inconsistency

Maintaining data consistency requires mechanisms to ensure the orderly execution of cooperating processes

Illustration of the problem: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 buffer and is decremented by the consumer after it consumes a buffer.

Page 5: Chapter 5:  Process Synchronization

5.5 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Producer

while (1) {

while (counter == BUFFER_SIZE)

; // do nothing

// produce an item and put in nextProduced

buffer[in] = nextProduced;

in = (in + 1) % BUFFER_SIZE;

counter++;

}

Page 6: Chapter 5:  Process Synchronization

5.6 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Consumer

while (1) {

while (counter == 0)

; // do nothing

nextConsumed = buffer[out];

out = (out + 1) % BUFFER_SIZE;

counter--;

// consume the item in nextConsumed

}

Page 7: Chapter 5:  Process Synchronization

5.7 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Updating of Shared Variable

counter++ could be implemented as

register1 = counter register1 = register1 + 1 counter = register1

counter-- could be implemented as

register2 = counter register2 = register2 - 1 counter = register2

Page 8: Chapter 5:  Process Synchronization

5.8 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Possible Execution Interleaving

register1 = counter register2 = counter register1 = register1 + 1 register2 = register2 - 1 counter = register1 counter = register2

Consider this execution interleaving:

S0: producer executes register1 = counter {register1 = 5}

S1: producer executes register1 = register1 + 1 {register1 = 6}

S2: consumer executes register2 = counter {register2 = 5}

S3: consumer executes register2 = register2 - 1 {register2 = 4}

S4: producer executes counter = register1 {counter = 6 }

S5: consumer executes counter = register2 {counter = 4}

Page 9: Chapter 5:  Process Synchronization

5.9 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Race Condition

A situation where several processes access and manipulate the same data concurrently and the outcome of the execution depends on the particular order in which the access takes place

Bottom level indivisible operation is architecture dependent. Typically, it is whatever takes place in one CPU cycle. Everything else can be divided

Lowest level atomic operation is called memory interlock or hardware arbiter. Everything else is built on top of that

Page 10: Chapter 5:  Process Synchronization

5.10 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Critical Section

In order to avoid having these unpredictable situations we need some way of synchronizing (establishing order) processes at their point of interaction

The segment of code in which the process may be changing common variables, updating a table, writing a file, and so on (i.e., segment of code containing at least one shared variable)

When one process is executing in its critical section, no other process should be allowed to execute in its critical section. That is, no two processes should be allowed to execute in their critical sections at the same time

Page 11: Chapter 5:  Process Synchronization

5.11 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Critical Section

Critical sections are used to artificially create indivisible operations

The critical section problem is to design a protocol that processes can use to cooperate. Each process must request permission to enter its critical section

Page 12: Chapter 5:  Process Synchronization

5.12 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

General Structure of a Process

do {

[entry section]

critical section

[exit section]

remainder section

} while (TRUE);

Page 13: Chapter 5:  Process Synchronization

5.13 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Solution to Critical-Section Problem

1. Mutual Execution is prohibited - If process Pi is executing in its critical section, then no other processes can be executing in their critical sections ESSENTIAL

2. Blocking is prohibited – A process that is not in its critical section must not prevent another process from getting into the critical section (i.e., it is not turn-taking) FOR EFFICIENCY

3. Indefinite Blocking is prohibited – The decision as to which process must enter its critical section next should be finite (i.e., no after-you syndrome) FOR EFFICIENCY

4. 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

Page 14: Chapter 5:  Process Synchronization

5.14 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Solution to Critical Section Problem

Assume that each process executes at a nonzero speed

No assumption concerning relative speed of the n processes

Page 15: Chapter 5:  Process Synchronization

5.15 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Initial Attempts to Solve Problem

Only 2 processes, Pi and Pj

General structure a process:

do {

entry section

critical section

exit section

remainder section

} while (TRUE);

Processes may share some common variables to synchronize their actions

Page 16: Chapter 5:  Process Synchronization

5.16 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Algorithm 1

Shared variables:

int turn;initially turn = i

turn = i Pi can enter its critical section

Process Pi Process Pj

do { do {

while (turn != i) ; while (turn != j) ;

critical section critical section

turn = j; turn = i;

remainder section remainder section

} while (TRUE); } while (TRUE);

Satisfies mutual exclusion, but blocking is not prohibited

Page 17: Chapter 5:  Process Synchronization

5.17 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Algorithm 2

Shared variables

boolean flag[2];initially flag [0] = flag [1] = false

flag [i] = true Pi ready to enter its critical section

Process Pi Process Pj

do { do {

flag[i] := true; flag[j] := true; while (flag[j]) ; while (flag[i]) ;

critical section critical section

flag [i] = false; flag [j] = false;

remainder section remainder section

} while (TRUE); } while (TRUE);

Satisfies mutual exclusion, but indefinite blocking is not prohibited

Page 18: Chapter 5:  Process Synchronization

5.18 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Solution to Critical-Section Problem

1. Mutual Execution is prohibited - If process Pi is executing in its critical section, then no other processes can be executing in their critical sections ESSENTIAL

2. Blocking is prohibited – A process that is not in its critical section must not prevent another process from getting into the critical section (i.e., it is not turn-taking) FOR EFFICIENCY

3. Indefinite Blocking is prohibited – The decision as to which process must enter its critical section next should be finite (i.e., no after-you syndrome) FOR EFFICIENCY

4. 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

Page 19: Chapter 5:  Process Synchronization

5.19 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Algorithm 3

Combined shared variables of algorithms 1 and 2

Process Pi Process Pj

do { do {

flag [i]:= true; flag [j]:= true;

turn = j; turn = i; while (flag [j] and turn = j); while (flag [i] and turn = i);

critical section critical section

flag [i] = false; flag [j] = false;

remainder section remainder section

} while (TRUE); } while (TRUE);

Meets all requirements; solves the critical-section problem for two processes

Page 20: Chapter 5:  Process Synchronization

5.20 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Peterson’s: Proof of Correctness

Mutual exclusion holds since:

For both P0 and P1 to be in their CS

both flag[0] and flag[1] must be true and:

turn=0 and turn=1 (at same time): impossible

Page 21: Chapter 5:  Process Synchronization

5.21 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Proof (“Progress”)

Progress requirement: Pi can be kept out of CS only if stuck in while loop

flag[j] = true and turn = j.

If Pj not ready to enter CS then flag[j] = false Pi can then enter its CS

If Pj has set flag[j], it is also in its while loop, then either P i or Pj will go depending on value of turn

Therefore the progress condition is met

Page 22: Chapter 5:  Process Synchronization

5.22 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Proof (“Bounded Waiting”) Suppose Pj gets to go this time

Can it go a second time without letting Pi go?

If Pj enters CS , then turn=j

but will then reset flag[ j]=false on exit:

allowing Pi to enter CS

What if Pj tries again, and has time to reset flag[j]=true before Pi gets to its CS?

It must also set turn=i

since Pi is (stuck) past the point where it sets turn= j:

Pi will get to enter CS

after at most one CS entry by Pj

Process Pi:

repeat

flag[i]:=true;

// I want in

turn:=j;

// but you can go first!

while(flag[j]&& turn==j)

; //(loop)

CS

flag[i]:=false;

// I’m done

RS

forever

Page 23: Chapter 5:  Process Synchronization

5.23 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Bakery Algorithm

Critical section problem for n processes

Before entering its critical section, process receives a number. Holder of the smallest number enters the critical section

If processes Pi and Pj receive the same number, if i < j, then Pi is served first; else Pj is served first

The numbering scheme always generates numbers in increasing order of enumeration; i.e., 1,2,3,3,3,3,4,5...

Page 24: Chapter 5:  Process Synchronization

5.24 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Bakery Algorithm

Notation < lexicographical order (ticket #, process id #)

(a,b) < (c,d) if a < c or if a = c and b < d

Shared data

boolean choosing[n];

int number[n];

Data structures are initialized to false and 0 respectively

Page 25: Chapter 5:  Process Synchronization

5.25 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Bakery Algorithm

while(1)}sectionremainder ;0][

section critical}

)));],[()],[&((&)0]![((while]);[(while

{ );;0(for;][

;1])1[],1[],0[max(][;][

{ do Process

inumber

iinumberjjnumberjnumberjchoosing

jnjjfalseichoosing

nnumbernumbernumberinumbertrueichoosing

Pi

Creating a number (first part of ticket)

Awaiting for permission to enter CS

Page 26: Chapter 5:  Process Synchronization

5.26 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Synchronization Hardware

We have seen software-based solutions to the critical section problem

In general, we can state that any solution to the critical-section problem requires a simple tool – a lock

Race conditions are prevented by requiring that critical regions be protected by locks. That is, a process must acquire a lock before entering a critical section; it releases the lock when it exits the critical section

Page 27: Chapter 5:  Process Synchronization

5.27 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

test_and_set Instruction

Definition:

boolean test_and_set (boolean *target) {

boolean rv = *target;

*target = TRUE;

return rv:

}

1. Executed atomically

2. Returns the original value of passed parameter

3. Set the new value of passed parameter to “TRUE”.

Page 28: Chapter 5:  Process Synchronization

5.28 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Solution using test_and_set()

Shared Boolean variable lock, initialized to FALSE Solution:

do { while (test_and_set(&lock))

; /* do nothing */

/* critical section */

lock = false;

/* remainder section */

} while (true);

Satisfies mutual exclusion, but indefinite blocking is not prohibited

Page 29: Chapter 5:  Process Synchronization

5.29 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

compare_and_swap Instruction

Definition: int compare _and_swap(int *value, int expected, int new_value) {

int temp = *value;

if (*value == expected)

*value = new_value;

return temp;

}

1. Executed atomically

2. Returns the original value of passed parameter “value”

3. Set the variable “value” the value of the passed parameter “new_value” but only if “value” ==“expected”. That is, the swap takes place only under this condition.

Page 30: Chapter 5:  Process Synchronization

5.30 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Solution using compare_and_swap

Shared integer “lock” initialized to 0; Solution:

do { while (compare_and_swap(&lock, 0, 1) != 0)

; /* do nothing */

/* critical section */

lock = 0;

/* remainder section */

} while (true);

Satisfies mutual exclusion, but indefinite blocking is not prohibited

Page 31: Chapter 5:  Process Synchronization

5.31 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Bounded-waiting Mutual Exclusion with test_and_set

do { waiting[i] = true; key = true; while (waiting[i] && key)

key = test_and_set(&lock);

waiting[i] = false;

/* critical section */

j = (i + 1) % n;

while ((j != i) && !waiting[j])

j = (j + 1) % n;

if (j == i)

lock = false;

else

waiting[j] = false;

/* remainder section */

} while (true);

do { waiting[j] = true; key = true; while (waiting[j] && key)

key = test_and_set(&lock);

waiting[j] = false;

/* critical section */

i = (j + 1) % n;

while ((i != j) && !waiting[i])

i = (i + 1) % n;

if (i == j)

lock = false;

else

waiting[i] = false;

/* remainder section */

} while (true);

Meets all requirements; solves the critical-section problem

Page 32: Chapter 5:  Process Synchronization

5.32 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Mutex Locks

Previous solutions are complicated and generally inaccessible to application programmers

OS designers build software tools to solve critical section problem

Simplest is mutex lock

Protect a critical section by first acquire() a lock then release() the lock Boolean variable indicating if lock is available or not

Calls to acquire() and release() must be atomic Usually implemented via hardware atomic instructions

But this solution requires busy waiting This lock therefore called a spinlock

Page 33: Chapter 5:  Process Synchronization

5.33 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

acquire() and release()

acquire() { while (!available)

; /* busy wait */

available = false;;

}

release() {

available = true;

}

do {

acquire lock

critical section

release lock

remainder section

} while (true);

Page 34: Chapter 5:  Process Synchronization

5.34 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Semaphores

The various hardware-based solutions to the critical section problem (using the TestAndSet() and Swap() instructions) are complicated for application programmers to use

To overcome this difficulty, we can use a synchronization tool called a semaphore

Dijkstra is well known as the inventor of the semaphore as the first software-oriented primitive to accomplish process synchronization [Dijkstra, 1968]

Dijkstra’s work on semaphores established over 30 years ago the foundation of modern techniques for accomplishing synchronization

Page 35: Chapter 5:  Process Synchronization

5.35 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Semaphore

Synchronization tool that provides more sophisticated ways (than Mutex locks) for process to synchronize their activities.

Semaphore S – integer variable Can only be accessed via two indivisible (atomic) operations

wait() and signal() Originally called P() and V()

Definition of the wait() operation

wait(S) { while (S <= 0)

; // busy wait

S--;

}

Definition of the signal() operation

signal(S) { S++;

}

Page 36: Chapter 5:  Process Synchronization

5.36 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Semaphore Usage

Counting semaphore – integer value can range over an unrestricted domain

Binary semaphore – integer value can range only between 0 and 1

Same as a mutex lock

Can solve various synchronization problems

Consider P1 and P2 that require S1 to happen before S2

Create a semaphore “synch” initialized to 0

P1:

S1;

signal(synch);

P2:

wait(synch);

S2;

Can implement a counting semaphore S as a binary semaphore

Page 37: Chapter 5:  Process Synchronization

5.37 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Semaphore Implementation

Must guarantee that no two processes can execute the wait() and signal() on the same semaphore at the same time

Thus, the implementation becomes the critical section problem where the wait and signal code are placed in the critical section

Could now have busy waiting in critical section implementation

But implementation code is short

Little busy waiting if critical section rarely occupied

Note that applications may spend lots of time in critical sections and therefore this is not a good solution

Page 38: Chapter 5:  Process Synchronization

5.38 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Semaphore Implementation with no Busy waiting

With each semaphore there is an associated waiting queue

Each entry in a waiting queue has two data items:

value (of type integer)

pointer to next record in the list

Two operations:

block – place the process invoking the operation on the appropriate waiting queue

wakeup – remove one of processes in the waiting queue and place it in the ready queue

typedef struct{

int value;

struct process *list;

} semaphore;

Page 39: Chapter 5:  Process Synchronization

5.39 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Implementation with no Busy waiting (Cont.)

wait(semaphore *S) {

S->value--;

if (S->value < 0) { add this process to S->list;

block();

}

}

signal(semaphore *S) {

S->value++;

if (S->value <= 0) { remove a process P from S->list;

wakeup(P);

}

}

Page 40: Chapter 5:  Process Synchronization

5.40 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Semaphore Primitives

Page 41: Chapter 5:  Process Synchronization

5.41 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Binary Semaphore Primitives

Page 42: Chapter 5:  Process Synchronization

5.42 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

A queue is used to hold processes waiting on the semaphore

Page 43: Chapter 5:  Process Synchronization

5.43 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Page 44: Chapter 5:  Process Synchronization

5.44 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Page 45: Chapter 5:  Process Synchronization

5.45 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Page 46: Chapter 5:  Process Synchronization

5.46 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Classical Problems of Synchronization

Producer-Consumer Problem

Readers and Writers Problem

Dining-Philosophers Problem

Page 47: Chapter 5:  Process Synchronization

5.47 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Buffer Structure

Page 48: Chapter 5:  Process Synchronization

5.48 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Page 49: Chapter 5:  Process Synchronization

5.49 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Page 50: Chapter 5:  Process Synchronization

5.50 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Page 51: Chapter 5:  Process Synchronization

5.51 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Page 52: Chapter 5:  Process Synchronization

5.52 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Page 53: Chapter 5:  Process Synchronization

5.53 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Page 54: Chapter 5:  Process Synchronization

5.54 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Bounded-Buffer Producer-Consumer Problem

Shared data

semaphore full, empty, mutex;

Initially:

full = 0, empty = n, mutex = 1

where n is the buffer size

Page 55: Chapter 5:  Process Synchronization

5.55 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Bounded-Buffer Producer-Consumer Problem

Producer

do { …

produce an item …

P(empty);P(mutex);

…add the item to the buffer

…V(mutex);V(full);

} while (TRUE);

The producer must wait for an empty space in the buffer

We must make sure that the producer and the consumer make changes to the shared buffer in a mutually exclusive manner

Page 56: Chapter 5:  Process Synchronization

5.56 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Bounded-Buffer Problem Consumer Process

Consumer

do { P(full)P(mutex);

…remove an item from the buffer

…V(mutex);V(empty);

…consume the item

…} while (TRUE);

We must make sure that the producer and the consumer make changes to the shared buffer in a mutually exclusive manner

The consumer must wait for an filled space in the buffer

Page 57: Chapter 5:  Process Synchronization

5.57 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Readers-Writers Problem

A database is to be shared among several concurrent processes. Some of these processes may want only to read the database, whereas others may want to update the database

We distinguish between these two types of processes by referring to the former as readers and to the latter as writers

Obviously, if two readers access the shared data simultaneously, nothing bad will happen

However, if a writer and some other process (either a reader or a writer) access the database simultaneously, chaos may ensue

Page 58: Chapter 5:  Process Synchronization

5.58 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Readers-Writers Problem To ensure that these difficulties do not arise, we require that the

writers have exclusive access to the shared database

This synchronization problem has been used to test nearly every new synchronization primitive

There are several variations of this problem, all involving priorities

The first and simplest one, referred to as the first readers-writers problem (Duh…), requires that no reader will be kept waiting unless a writer has already obtained permission to use the shared object (i.e., no reader should wait for other readers to finish simply because a writer is waiting) NOTE: writers may starve

The second readers-writers problem requires that, once a writer is ready, that writer performs its write as soon as possible (i.e., if a writer is waiting, no new readers may start reading) NOTE: readers may starve

Page 59: Chapter 5:  Process Synchronization

5.59 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

First Readers-Writers Problem

Shared data

semaphore mutex, wrt;int readcount;

Initially

mutex = 1, wrt = 1, readcount = 0

Page 60: Chapter 5:  Process Synchronization

5.60 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

First Readers-Writers Problem

Writer

do {P(wrt); …writing is performed …V(wrt);

} while (TRUE);

A writer will wait if either another writer is currently writing or one or more readers are currently reading

Page 61: Chapter 5:  Process Synchronization

5.61 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

First Readers-Writers Problem

Reader

do{P(mutex);readcount++;if (readcount == 1)

P(wrt);V(mutex);

…reading is performed

…P(mutex);readcount--;if (readcount == 0)

V(wrt);

V(mutex);

} while(TRUE);

A reader will wait only if a writer is currently writing. Note that if readcount == 1, no reader is currently reading and thus that is the only time that a reader has to make sure that no writer is currently writing (i.e., if readcount > 1, there is at least one reader reading and thus the new reader does not have to wait

We must make sure that readers update the shared variable readcount in a mutually exclusive manner

Page 62: Chapter 5:  Process Synchronization

5.62 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Dining-Philosophers Problem

Philosophers spend their lives alternating thinking and eating

Don’t interact with their neighbors, occasionally try to pick up 2 chopsticks (one at a time) to eat from bowl

Need both to eat, then release both when done

In the case of 5 philosophers

Shared data

Bowl of rice (data set)

Semaphore chopstick [5] initialized to 1

Page 63: Chapter 5:  Process Synchronization

5.63 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Dining-Philosophers Problem Algorithm

The structure of Philosopher i:do {

wait (chopstick[i] );

wait (chopStick[ (i + 1) % 5] );

// eat

signal (chopstick[i] );

signal (chopstick[ (i + 1) % 5] );

// think

} while (TRUE);

What is the problem with this algorithm?

Page 64: Chapter 5:  Process Synchronization

5.64 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Dining-Philosophers Problem Algorithm (Cont.)

Deadlock handling

Allow at most 4 philosophers to be sitting simultaneously at the table.

Allow a philosopher to pick up the forks only if both are available (picking must be done in a critical section.

Use an asymmetric solution -- an odd-numbered philosopher picks up first the left chopstick and then the right chopstick. Even-numbered philosopher picks up first the right chopstick and then the left chopstick.

Page 65: Chapter 5:  Process Synchronization

5.65 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Problems with Semaphores

Incorrect use of semaphore operations:

signal (mutex) …. wait (mutex)

wait (mutex) … wait (mutex)

Omitting of wait (mutex) or signal (mutex) (or both)

Deadlock and starvation are possible.

Page 66: Chapter 5:  Process Synchronization

5.66 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Monitors

A high-level abstraction that provides a convenient and effective mechanism for process synchronization

Abstract data type, internal variables only accessible by code within the procedure

Only one process may be active within the monitor at a time But not powerful enough to model some synchronization schemes

monitor monitor-name{// shared variable declarationsprocedure P1 (…) { …. }

procedure Pn (…) {……}

Initialization code (…) { … }}

}

Page 67: Chapter 5:  Process Synchronization

5.67 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Schematic view of a Monitor

Page 68: Chapter 5:  Process Synchronization

5.68 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Condition Variables

condition x, y; Two operations are allowed on a condition variable:

x.wait() – a process that invokes the operation is suspended until x.signal()

x.signal() – resumes one of processes (if any) that invoked x.wait() If no x.wait() on the variable, then it has no effect on

the variable

Page 69: Chapter 5:  Process Synchronization

5.69 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Monitor with Condition Variables

Page 70: Chapter 5:  Process Synchronization

5.70 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Condition Variables Choices

If process P invokes x.signal(), and process Q is suspended in x.wait(), what should happen next?

Both Q and P cannot execute in paralel. If Q is resumed, then P must wait

Options include

Signal and wait – P waits until Q either leaves the monitor or it waits for another condition

Signal and continue – Q waits until P either leaves the monitor or it waits for another condition

Both have pros and cons – language implementer can decide

Monitors implemented in Concurrent Pascal compromise

P executing signal immediately leaves the monitor, Q is resumed

Implemented in other languages including Mesa, C#, Java

Page 71: Chapter 5:  Process Synchronization

5.71 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Monitor Solution to Dining Philosophers

monitor DiningPhilosophers{

enum { THINKING; HUNGRY, EATING) state [5] ;condition self [5];

void pickup (int i) { state[i] = HUNGRY; test(i); if (state[i] != EATING) self[i].wait;

}

void putdown (int i) { state[i] = THINKING;

// test left and right neighbors test((i + 4) % 5); test((i + 1) % 5);

}

Page 72: Chapter 5:  Process Synchronization

5.72 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Solution to Dining Philosophers (Cont.)

void test (int i) { if ((state[(i + 4) % 5] != EATING) && (state[i] == HUNGRY) && (state[(i + 1) % 5] != EATING) ) { state[i] = EATING ;

self[i].signal () ; }

}

initialization_code() { for (int i = 0; i < 5; i++) state[i] = THINKING; }

}

Page 73: Chapter 5:  Process Synchronization

5.73 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Each philosopher i invokes the operations pickup() and putdown() in the following sequence:

DiningPhilosophers.pickup(i);

EAT

DiningPhilosophers.putdown(i);

No deadlock, but starvation is possible

Solution to Dining Philosophers (Cont.)

Page 74: Chapter 5:  Process Synchronization

5.74 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Monitor Implementation Using Semaphores

Variables

semaphore mutex; // (initially = 1) semaphore next; // (initially = 0) int next_count = 0;

Each procedure F will be replaced by

wait(mutex); …

body of F; …if (next_count > 0)signal(next)

else signal(mutex);

Mutual exclusion within a monitor is ensured

Page 75: Chapter 5:  Process Synchronization

5.75 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Monitor Implementation – Condition Variables

For each condition variable x, we have:

semaphore x_sem; // (initially = 0)int x_count = 0;

The operation x.wait can be implemented as:

x_count++;if (next_count > 0)

signal(next);else

signal(mutex);wait(x_sem);x_count--;

Page 76: Chapter 5:  Process Synchronization

5.76 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Monitor Implementation (Cont.)

The operation x.signal can be implemented as:

if (x_count > 0) {next_count++;signal(x_sem);wait(next);next_count--;

}

Page 77: Chapter 5:  Process Synchronization

5.77 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Resuming Processes within a Monitor

If several processes queued on condition x, and x.signal() executed, which should be resumed?

FCFS frequently not adequate

conditional-wait construct of the form x.wait(c)

Where c is priority number

Process with lowest number (highest priority) is scheduled next

Page 78: Chapter 5:  Process Synchronization

5.78 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Allocate a single resource among competing processes using priority numbers that specify the maximum time a process plans to use the resource

R.acquire(t); ... access the resurce; ...

R.release;

Where R is an instance of type ResourceAllocator

Single Resource allocation

Page 79: Chapter 5:  Process Synchronization

5.79 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

A Monitor to Allocate Single Resource

monitor ResourceAllocator {

boolean busy; condition x; void acquire(int time) {

if (busy) x.wait(time);

busy = TRUE; } void release() {

busy = FALSE; x.signal();

} initialization code() {

busy = FALSE; }

}

Page 80: Chapter 5:  Process Synchronization

5.80 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Synchronization Examples

Solaris

Windows

Linux

Pthreads

Page 81: Chapter 5:  Process Synchronization

5.81 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Solaris 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 Starts as a standard semaphore spin-lock

If lock held, and by a thread running on another CPU, spins

If lock held by non-run-state thread, block and sleep waiting for signal of lock being released

Uses condition variables

Uses 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 Turnstiles are per-lock-holding-thread, not per-object

Priority-inheritance per-turnstile gives the running thread the highest of the priorities of the threads in its turnstile

Page 82: Chapter 5:  Process Synchronization

5.82 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Windows Synchronization

Uses interrupt masks to protect access to global resources on uniprocessor systems

Uses spinlocks on multiprocessor systems

Spinlocking-thread will never be preempted

Also provides dispatcher objects user-land which may act mutexes, semaphores, events, and timers

Events

An event acts much like a condition variable

Timers notify one or more thread when time expired

Dispatcher objects either signaled-state (object available) or non-signaled state (thread will block)

Page 83: Chapter 5:  Process Synchronization

5.83 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Linux Synchronization

Linux:

Prior to kernel Version 2.6, disables interrupts to implement short critical sections

Version 2.6 and later, fully preemptive

Linux provides:

Semaphores

atomic integers

spinlocks

reader-writer versions of both

On single-cpu system, spinlocks replaced by enabling and disabling kernel preemption

Page 84: Chapter 5:  Process Synchronization

5.84 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Pthreads Synchronization

Pthreads API is OS-independent

It provides:

mutex locks

condition variable

Non-portable extensions include:

read-write locks

spinlocks

Page 85: Chapter 5:  Process Synchronization

5.85 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Alternative Approaches

Transactional Memory

OpenMP

Functional Programming Languages

Page 86: Chapter 5:  Process Synchronization

5.86 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

A memory transaction is a sequence of read-write operations to memory that are performed atomically.

void update() {

/* read/write memory */ }

Transactional Memory

Page 87: Chapter 5:  Process Synchronization

5.87 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

OpenMP is a set of compiler directives and API that support parallel progamming.

void update(int value) {

#pragma omp critical{

count += value}

}

The code contained within the #pragma omp critical directive is treated as a critical section and performed atomically.

OpenMP

Page 88: Chapter 5:  Process Synchronization

5.88 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

Functional programming languages offer a different paradigm than procedural languages in that they do not maintain state.

Variables are treated as immutable and cannot change state once they have been assigned a value.

There is increasing interest in functional languages such as Erlang and Scala for their approach in handling data races.

Functional Programming Languages

Page 89: Chapter 5:  Process Synchronization

Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition

End of Chapter 5