0% found this document useful (0 votes)
5 views

Lecture_4

The document discusses key concepts in operating systems, focusing on process synchronization, race conditions, and critical-section problems. It outlines various solutions such as mutex locks, semaphores, and algorithms like Peterson’s solution, while also addressing issues like deadlocks and priority inversion. Additionally, it presents classic synchronization problems including the Bounded-Buffer Problem, Readers-Writers Problem, and Dining-Philosophers Problem.

Uploaded by

Ahmed Khaled
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Lecture_4

The document discusses key concepts in operating systems, focusing on process synchronization, race conditions, and critical-section problems. It outlines various solutions such as mutex locks, semaphores, and algorithms like Peterson’s solution, while also addressing issues like deadlocks and priority inversion. Additionally, it presents classic synchronization problems including the Bounded-Buffer Problem, Readers-Writers Problem, and Dining-Philosophers Problem.

Uploaded by

Ahmed Khaled
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 29

Assiut University

Course Title: Operating Systems


CourseClick to Code:
add text CS321
Click to add text

Prof. Khaled F.
Hussain
Reference
• Silberschatz, Abraham, Peter B. Galvin, and Greg
Gagne. Operating system concepts. John Wiley & Sons.
Process Synchronization
• 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, is called a race condition.
• counter++
register1 = counter
register1 = register1 + 1
counter = register1

• counter—
register2 = counter
register2 = register2 − 1
counter = register2
Race condition
• T0: producer execute register1 = counter {register1 = 5}
• T1: 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 {counter = 6}
• T5: consumer execute counter = register2 {counter = 4}

• Notice that we have arrived at the incorrect state “counter == 4”,


The Critical-Section Problem

• Consider a system consisting of


n processes {P0, P1, ..., Pn−1}.
Each process has a segment of
code, called a critical section,
in which the process may be
changing common variables,
updating a table, writing a file,
and so on.
The Critical-Section Problem (Cont.)
• A solution to the critical-section problem must satisfy the following three requirements:
• 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 deciding which will enter its critical
section next, and this selection cannot be postponed indefinitely.
• Bounded waiting. There exists a bound, or limit, 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.
Algorithm for Process Pi

do {

while (turn == j);

critical section
turn = j;

remainder section
} while (true);
Peterson’s Solution
Peterson’s Solution (Cont.)
• To prove that this solution is correct. We need to show that:
• Mutual exclusion is preserved.
• The progress requirement is satisfied.
• The bounded-waiting requirement is met.
Synchronizati
on Hardware
• The critical-section problem could
be solved simply in a single-
processor environment if we could
prevent interrupts from occurring
while a shared variable was being
modified.
• In this way, we could be sure that
the current sequence of instructions
would be allowed to execute in
order without preemption.
• No other instructions would be run,
so no unexpected modifications
could be made to the shared
variable.
• This is often the approach taken by
nonpreemptive kernels.
Synchronization Hardware (Cont.)
Mutex Locks
• The previous hardware-based solutions to the critical-section problem are
complicated as well as generally inaccessible to application programmers.
• Operating-systems designers build software tools to solve the critical-section problem. The
simplest of these tools is the mutex lock. (In fact, the term mutex is short for mutual
exclusion.)
• We use the mutex lock to protect critical regions and thus prevent race conditions.
• That is, a process must acquire the lock before entering a critical section; it releases the lock
when it exits the critical section.
• The acquire()function acquires the lock, and the release() function releases the lock
acquire() {
while (!available); /* busy wait */
available = false; }

release() { available = true; }


Spinlock
• The main disadvantage of the implementation given is that it requires busy waiting.
While a process is in its critical section, any other process that tries to enter its critical
section must loop continuously in the call to acquire().
• In fact, this type of mutex lock is also called a spinlock because the process “spins”
while waiting for the lock to become available.
• Busy waiting wastes CPU cycles
Semaphores
• A semaphore S is an integer variable that, apart from initialization, is accessed only
through two standard atomic operations: wait() and signal(). The wait() operation was
originally termed P (from the Dutch proberen, “to test”); signal() was originally called
V (from verhogen, “to increment”).
wait(S) {
while (S <= 0) ; // busy wait
S--;
}

signal(S) { S++;}
Semaphore Usage
• Operating systems often distinguish between counting and binary semaphores.
• 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. Thus, binary
semaphores behave similarly to mutex locks. In fact, on systems that do not provide
mutex locks, binary semaphores can be used instead for providing mutual exclusion.
Semaphore Implementation
• To implement semaphores, we define a semaphore as follows:
typedef struct {
int value;
struct process *list;
} semaphore;

wait(semaphore *S) {
S->value--;
if (S->value < 0) {
add this process to S->list;
block();
}
}
Semaphore Implementation (Cont.)
signal(semaphore *S) { S->value++;
if (S->value <= 0) {
remove a process P from S->list;
wakeup(P);
}
}
Deadlocks
and
Starvation
• The implementation of a
semaphore with a waiting queue
may result in a situation where
two or more processes are
waiting indefinitely for an event
that can be caused only by one
of the waiting processes. When
such a state is reached, these
processes are said to be
deadlocked.
• To illustrate this, consider a
system consisting of two
processes, P0 and P1, each
accessing two semaphores, S and
Q, set to the value 1:
Priority Inversion
• A scheduling challenge arises when a higher-priority process needs to read or modify
kernel data that are currently being accessed by a lower-priority process—or a chain of
lower-priority processes. Since kernel data are typically protected with a lock, the
higher-priority process will have to wait for a lower-priority one to finish with the
resource.
Classic Problems of Synchronization
• The Bounded-Buffer Problem
• The Readers–Writers Problem
• The Dining-Philosophers Problem
The Bounded-Buffer Problem
int n;
semaphore mutex = 1;
semaphore empty = n;
semaphore full = 0

• The structure of the producer process


do { . . .
/* produce an item in next produced */
...
wait(empty);
wait(mutex);
...
/* add next produced to the buffer */
...
signal(mutex);
signal(full);
} while (true);
The Bounded-Buffer Problem (Cont.)
• The structure of the consumer process
do {
wait(full);
wait(mutex);
...
/* remove an item from buffer to next consumed */
...
signal(mutex);
signal(empty);
...
/* consume the item in next consumed */
...
} while (true);
The Readers–Writers Problem
• Suppose that a database is to be shared among several concurrent processes.
• If two readers access the shared data simultaneously, no adverse effects will result.
• However, if a writer and some other process (either a reader or a writer) access the
database simultaneously, chaos may ensue.
• Writers have exclusive access to the shared database while writing to the database.
The Readers–Writers Problem
(Cont.)
semaphore rw_mutex = 1;
semaphore mutex = 1;
int read count = 0;

• The structure of a writer process


do {
wait(rw_mutex );
...
/* writing is performed */
...
signal(rw_mutex );
} while (true);
The Readers–Writers Problem
(Cont.)
• The structure of a reader process
do {
wait(mutex);
read_count++;
if (read_count == 1)
wait(rw_mutex );
signal(mutex);
...
/* reading is performed */
...
wait(mutex);
read count--;
if (read_count == 0)
signal(rw_mutex );
signal(mutex);
} while (true);
The Dining-Philosophers Problem
The structure of philosopher i

semaphore chopstick[5]; • Although this solution guarantees that


no two neighbours are eating
simultaneously, it nevertheless must
do { be rejected because it could create a
wait(chopstick[i]); deadlock.
wait(chopstick[(i+1) % 5]); • Suppose that all five philosophers
... become hungry at the same time and
each grabs her left chopstick.
/* eat for awhile */
... • All the elements of chopstick will now
be equal to 0. When each philosopher
signal(chopstick[i]);
tries to grab her right chopstick, she
signal(chopstick[(i+1) % 5]); will be delayed forever.
...
/* think for awhile */
...
} while (true);
The Dining-Philosophers Problem
(Cont.)
• Several possible remedies to the deadlock problem are replaced by:
• Allow at most four philosophers to be sitting simultaneously at the table.
• Allow a philosopher to pick up her chopsticks only if both chopsticks are
available (to do this, she must pick them up in a critical section).
• Use an asymmetric solution—that is, an odd-numbered philosopher picks
up first her left chopstick and then her right chopstick, whereas an even
numbered philosopher picks up her right chopstick and then her left
chopstick.

You might also like