Download Synchronization Part-I - McMaster Computing and Software

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

DNIX wikipedia , lookup

Burroughs MCP wikipedia , lookup

Distributed operating system wikipedia , lookup

Process management (computing) wikipedia , lookup

Transcript
Chapter 5: Process
Synchronization (Part - 1)
Operating System Concepts – 9th Edition
Modified by Dr. Neerja Mhaskar for CS 3SH3
Silberschatz, Galvin and Gagne ©2013
Background
 Processes (and threads) can execute concurrently
 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 (Figure next slide) 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 item and is decremented by the consumer after it
consumes a buffer.
Operating System Concepts – 9th Edition
5.2
Silberschatz, Galvin and Gagne ©2013
Producer Consumer Problem
Buffer
Producer
Operating System Concepts – 9th Edition
Consumer
5.3
Silberschatz, Galvin and Gagne ©2013
Producer
while (true) {
/* produce an item in next produced */
while (counter == BUFFER_SIZE) ;
/* do nothing */
buffer[in] = next_produced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}

buffer = Shared buffer, circular array

BUFFER_SIZE = max. size of the buffer.

counter that keeps track of the number of full buffers
Operating System Concepts – 9th Edition
5.4
Silberschatz, Galvin and Gagne ©2013
Consumer
while (true) {
while (counter == 0)
; /* do nothing */
next_consumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
/* consume the item in next consumed */
}
Operating System Concepts – 9th Edition
5.5
Silberschatz, Galvin and Gagne ©2013
Race 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

Consider this execution interleaving with “counter = 5” initially:
S0: producer execute register1 = counter
S1: producer execute register1 = register1 + 1
S2: consumer execute register2 = counter
S3: consumer execute register2 = register2 – 1
S4: producer execute counter = register1
S5: consumer execute counter = register2
Operating System Concepts – 9th Edition
5.6
{register1 = 5}
{register1 = 6}
{register2 = 5}
{register2 = 4}
{counter = 6 }
{counter = 4}
Silberschatz, Galvin and Gagne ©2013
Critical Section Problem
 Consider system of n processes {p0, p1, … pn-1}
 Each process has critical section segment of code

Process may be changing common variables, updating
table, writing file, etc
 Goal: When one process is in its critical section, no other
process may be in its critical section and each process gets a
turn (in bounded time) to execute its critical section
 Critical section problem is to design protocol to achieve this
goal.
 Each process must ask permission to enter critical section in
entry section, may follow critical section with exit section,
then remainder section
 We will use Critical Section and CS interchangeably
Operating System Concepts – 9th Edition
5.7
Silberschatz, Galvin and Gagne ©2013
Critical Section
 General structure of process Pi
Operating System Concepts – 9th Edition
5.8
Silberschatz, Galvin and Gagne ©2013
Solution requirement to CS 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
some processes wish to enter their critical sections, then
1.
2.
Only those processes not executing in their remainder section
can participate in deciding which will enter its CS next
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
Operating System Concepts – 9th Edition
5.9
Silberschatz, Galvin and Gagne ©2013
Critical-Section Handling in OS
 Preemption: The operating system removes the process
running on the CPU after it has executed for the specified
period of time, and brings another program in to run on the
CPU. This act is called preemption.
 Two approaches taken by the kernel to handle CS:

Preemptive – allows preemption of process when running
in kernel mode

Non-preemptive – runs until exits kernel mode, blocks, or
voluntarily yields CPU

Essentially free of race conditions in kernel mode
Why would you prefer a Preemptive kernel?
Operating System Concepts – 9th Edition
5.10
Silberschatz, Galvin and Gagne ©2013
Peterson’s Solution
 Good algorithmic description of solving the problem
 Two concurrent process solution (P0 and P1)
 Assume that the
load and store machine-language
instructions are atomic; that is, cannot be interrupted
 The two processes share two variables:

int turn;

Boolean flag[2]
 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. flag[i] = true implies that process Pi is
ready!
 Values of flag initialized to False.
Operating System Concepts – 9th Edition
5.11
Silberschatz, Galvin and Gagne ©2013
Algorithm for Process Pi
do {
flag[i] = true;
turn = j;
while (flag[j] && turn = = j);
Entry Section
critical section
Exit Section
flag[i] = false;
remainder section
} while (true);

Processes can execute this code arbitrarily many times.

If i=0 then j=1 and visa versa.

While loop in the entry section functions like a filter/trap.
Operating System Concepts – 9th Edition
5.12
Silberschatz, Galvin and Gagne ©2013
Correctness of Peterson’s Solution
 All three CS requirements are met.
 Mutual exclusion is preserved

If both P0 and P1 want to enter their CS this will result in both
flag[0] = T and flag[1] = T

But turn = 0 or turn = 1.

Since turn can be either 0 or 1 at any given time only one
process can enter and thus execute in its CS.
Operating System Concepts – 9th Edition
5.13
Silberschatz, Galvin and Gagne ©2013
Correctness of Peterson’s Solution
 Progress is satisfied:

At any given time if both P0 and P1 want to enter the CS the
decision which process enters its CS happens in finite time.

If both P0 and P1 want to enter this will result in both
flag[0] = T and flag[1] = T

But turn = 0 or turn = 1. The value of turn depends on
the order of execution of the statement turn = j; in both
processes P0 and P1

The value of turn will determine which process gets to enter
its CS first.

This decision is made in finite time.

Additionally if process P0 (or P1 ) is executing in its remainder CS,
it does not affect the other process from entering its CS.

Therefore progress is satisfied.
Operating System Concepts – 9th Edition
5.14
Silberschatz, Galvin and Gagne ©2013
Correctness of Peterson’s Solution
 Bounded waiting is satisfied:

Consider, P0 and P1 both want to enter their CS.

From Progress we know that one will enter its CS (lets say P0
gets its turn)

When P0 is in CS then flag[0]=T and flag[1] = T and
turn = 0

When P0 exists CS then flag[0]=F, flag[1] = T and
turn = 0

Thus, P1 is the process that gets to enter its CS next.

Therefore, bounded waiting is satisfied, and a process will
enter its critical section after at most one entry by the other
process (bounded waiting).
Operating System Concepts – 9th Edition
5.15
Silberschatz, Galvin and Gagne ©2013
Some pointers to check correctness of CS solution
 The trickiest requirement to prove is progress

If it is possible for ALL processes to be stuck at the while loop statement
(remember processes can be preempted any time and any no. of
times).


Check if a process can enter its CS arbitrarily many times if the other
processes do not wish to enter their CS. If this is not possible, then


Progress requirement (condition 2) is violated.
Progress requirement (condition 1) is violated.
If strict order exists in which processes access their CS, then again

Progress requirement (condition 1) is violated.
 To check if bounded waiting is achieved

Check if it is possible for a process to enter its CS infinitely many times
without giving other processes that wish to enter their CS a turn.
Operating System Concepts – 9th Edition
5.16
Silberschatz, Galvin and Gagne ©2013
Synchronization Hardware
 Peterson’s Algorithm drawbacks: works for only two processes
and relies atomic load and store machine instructions.
 Systems with single processors – could disable interrupts
 Currently running code would execute without preemption

Generally too inefficient on a multiprocessor systems
 Disabling interrupts on a multiprocessor can be time
consuming and system efficiency is decreased.
 All solutions hereafter based on idea of locking
 Protecting critical regions via locks
 Modern machines provide special atomic hardware instructions

Test_and_Set()
 Compare_and_swap()
Operating System Concepts – 9th Edition
5.17
Silberschatz, Galvin and Gagne ©2013
Solution to Critical-section Problem
For Multiple Processes: Using Locks
do {
acquire lock
critical section
release lock
remainder section
} while (TRUE);
Operating System Concepts – 9th Edition
5.18
Silberschatz, Galvin and Gagne ©2013
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”.
Operating System Concepts – 9th Edition
5.19
Silberschatz, Galvin and Gagne ©2013
Solution using test_and_set()

Shared Boolean variable lock. Initially lock=FALSE (lock is available)

Suppose a process Pi wants to enter its CS
do {
while (test_and_set(&lock));

/* do nothing */
Sets lock=True
and returns False
/* critical section */
lock = false;
/* remainder section */
} while (true);
Operating System Concepts – 9th Edition
5.20
Silberschatz, Galvin and Gagne ©2013
Solution using test_and_set()
Mutual Exclusion
 Suppose process Pj wants to enter its CS, while Pi is
executing in its CS. It sees lock=True.

do {
Returns True, and
also, lock=True,
so waits.
while (test_and_set(&lock))
; /* do nothing */
/* critical section */
lock = false;
/* remainder section */
} while (true);
 Process waits to get the lock at the while loop.
 Therefore when any process Pi is executing in its CS,
another process cannot enter its CS and mutual
exclusion is achieved.
Operating System Concepts – 9th Edition
5.21
Silberschatz, Galvin and Gagne ©2013
Solution using test_and_set()
Progress and Bounded waiting
 Initially lock=FALSE, multiple processes try to enter
If multiple processes want to enter CS, only one of them
gets to execute test and set (also in finite time)
 A process executing in its remainder section does not get
to block another process from entering the CS, since it
has already released the lock.
 However the same process can enter CS repeatedly, without
giving a turn to other processes. Hence, bounded wait is not
achieved.

Operating System Concepts – 9th Edition
5.22
Silberschatz, Galvin and Gagne ©2013
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. Compares the integer stored in “value” to the integer value stored in
expected. If they are equal then stores the integer value of “new_value”
in “value”.
Operating System Concepts – 9th Edition
5.23
Silberschatz, Galvin and Gagne ©2013
Solution using compare_and_swap
 Shared integer “lock” initialized to 0; (lock is available)
 Expected value = 0 (lock is available)
 New value = 1 (lock is unavailable)
 Solution:
do {
while (compare_and_swap(&lock, 0, 1) != 0)
; /* do nothing */
/* critical section */
lock = 0;
/* remainder section */
} while (true);
Operating System Concepts – 9th Edition
5.24
Silberschatz, Galvin and Gagne ©2013
Solution using compare_and_swap()

Shared int variable lock. Initially lock=0 (lock is available)

Suppose a process Pi wants to enter its CS
do {
while (compare_and_swap(&lock, 0, 1) != 0)
; /* do nothing */
Checks if lock=0,
in this case it is,
therefore resets
lock = 1 and returns
0
/* critical section */
lock = 0;
/* remainder section */
} while (true);
Operating System Concepts – 9th Edition
5.25
Silberschatz, Galvin and Gagne ©2013
Solution using compare_and_swap()
Mutual Exclusion Cont.

Shared int variable lock. Initially lock=0

Process Pj wants to enter CS, while Pi is executing in its CS.
it sees lock=1.
do {
while (compare_and_swap(&lock, 0, 1) != 0)
; /* do nothing */
/* critical section */
Checks if lock=0,
in this case it is not,
therefore does not
reset it and simply
returns 1.
lock = 0;
/* remainder section */
} while (true);

Process waits to get the lock at the while loop.

Therefore when any process Pi is executing in its CS, another
process cannot enter its CS and mutual exclusion is
achieved.
Operating System Concepts – 9th Edition
5.26
Silberschatz, Galvin and Gagne ©2013
Solution using compare_and_swap()
Progress and bounded wait
 Initially lock=0 (open), multiple processes try to enter
If multiple processes want to enter CS, only one of them
gets to execute compare_and_swap() (also in finite time)
 A process executing in its remainder section does not get
to block another process from entering the CS, since it
has already released the lock.
 However the same process can enter CS repeatedly, without
giving a turn to other processes. Hence, bounded wait is not
achieved.

Operating System Concepts – 9th Edition
5.27
Silberschatz, Galvin and Gagne ©2013
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
Operating System Concepts – 9th Edition
5.28
Silberschatz, Galvin and Gagne ©2013
acquire() and release()
 Shared Boolean available. Available = True -> lock is available and Avaiable
= False -> lock is unavailable.
 Acquire Operation:
acquire() {
while (!available)
; /* busy wait */
available = false;
}

Release Operation:
release() {
available = true;
}
Operating System Concepts – 9th Edition
5.29
Silberschatz, Galvin and Gagne ©2013
Solution using Mutex lock
do {
acquire(); /*acquire lock*/
critical section
release(); /*release lock*/
remainder section
} while (true);
Operating System Concepts – 9th Edition
5.30
Silberschatz, Galvin and Gagne ©2013
Issues with Hardware Instructions and Mutex Locks
 The issue with the previous lock based solutions (hardware instructions and
mutex ) busy waiting

Busy waiting consumes CPU cycles without doing any useful work.

This type of lock is known as a spinlock, because the lock just sits
there and spins while it waits.

Although busy waiting wastes CPU cycles, it saves time by not invoking
context switches

Therefore, useful in multi-processing systems when the wait time is
expected to be short - One thread spins on one processor while another
completes their critical section on another processor.
Operating System Concepts – 9th Edition
5.31
Silberschatz, Galvin and Gagne ©2013
Pthreads Synchronization
 Pthreads API is available for programmers at the user level and
is not part of any particular kernel.

Provides mutex locks, condition variables, and read–write
locks for thread synchronization.

Mutex locks are the fundamental synchronization technique
used.

pthread_mutex_t data type for mutex locks.

mutex created with pthread_mutex_init()function.

pthread_mutex_lock();

pthread_mutex_unlock();
Operating System Concepts – 9th Edition
5.32
Silberschatz, Galvin and Gagne ©2013
Pthread Mutex Example
/*Declaring mutex*/
pthread_mutex_t mutex;
/*Initialize mutex, it returns 0
Null indicates default
mutex attributes passed.
if mutex initialized with no errors.*/
if (pthread_mutex_init(&mutex, NULL) !=0){
printf("Error in initializing mutex \n");
}
Returns 0 when mutex
created with no errors,
otherwise returns non zero
value.
/*Acquire mutex lock*/
pthread_mutex_lock(&mutex);
/*Critical Section*/
/*Release mutex locks*/
pthread_mutex_unlock(&mutex);
Operating System Concepts – 9th Edition
5.33
Silberschatz, Galvin and Gagne ©2013
End of Chapter 5
Operating System Concepts – 9th Edition
Silberschatz, Galvin and Gagne ©2013