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

Process-Synchronization 1

Uploaded by

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

Process-Synchronization 1

Uploaded by

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

CENG 302

OPERATİNG SYSTEMS

Dr. Mansur Alp TOÇOĞLU


In this chapter,
• Process Synchronization
• Critical Section Problem
• Race Condition
• Peterson Solution
• Mutex
• Semafor
topics will be explained.

2
PROBLEM DEFINITION
• Concurrent (at the same time) access to shared
data (memory space, file) or a shared resource is
always prone to problems and may cause
inconsistency.
• The way to ensure consistency is

to create a mechanism where processes or threads working together can do their


jobs in a precise order.

3
PRODUCER/CONSUMER PROBLEM

• Let's consider the Producer-Consumer problem


mentioned above, where processing is done on a limited
buffer.
• One of the major problems with this metaphor was that a
maximum of BUFFER_SIZE - 1 element could be used.
• Now let's think of a solution that will completely use the
entire buffer:
• Let's assume that there is an integer counter that will keep the number
of elements in the buffer.
• Let its initial value be 0.
• When the producer produces a new element, the counter increases
by one.
• When the consumer consumes an element from the buffer, the
counter decreases by one.

4
PRODUCER/CONSUMER PROBLEM
(CONTINUES…)

• Producer Process
Old code New code
item next_produced; item next_produced;
while (true) while (true) {
{ /* produce an item and */
/* produce an item in next_produced */ /* put in next_produced*/

while (((in + 1) % BUFFER_SIZE) == while (counter == BUFFER_SIZE)


out) ; // do nothing buffer is full
; /* do nothing, buffer is full*/
buffer[in] = next_produced;
buffer[in] = next_produced; in = (in + 1) % BUFFER_SIZE;
in = (in + 1) % BUFFER_SIZE; counter++;
} }

5
PRODUCER/CONSUMER PROBLEM
(CONTINUES…)

• Consumer Process
Old code New code
item next_consumed; item next_consumed;
while (true) { while (true) {
while (counter == 0)
while (in == out) ; // do nothing buffer empty
; /* do nothing, buffer is empty*/
next_consumed = buffer[out];
next-consumed = buffer[out]; out = (out + 1) % BUFFER_SIZE;
out = (out + 1) % BUFFER SIZE; counter--;
/* consume the item in next cons. */ /* consume the item in next cons. */
} }

6
PRODUCER/CONSUMER PROBLEM
(CONTINUES…)

• When we examine both processes one by one, they


may seem to be designed correctly, but when it comes to
concurrent execution, they may not produce consistent
results.
• For example: Let's assume that counter++ and counter--
statements run simultaneously when counter=5.
• After producer and consumer run concurrently
• The value of the variable can be 4, 5 or 6.
• Actually, there is only one result and that is 5.
• Let's try to create this problem by looking at it from a
different perspective.

7
PRODUCER/CONSUMER PROBLEM
(CONTINUES…)

• Machine commands for counter++ can be as follows.

• Machine commands for counter-- may be as


follows.

• register1, register2 are local CPU registers.


8
PRODUCER/CONSUMER PROBLEM
(CONTINUES…)

• Let's assume that the counter++ and counter--


calculations are concurrent.
• In other words, the producer and the consumer should
try to update the memory at the same time.
• In this case, states can be nested in machine language.

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


S1: producer execute register1 = register1 + 1 {register1 = 6}
S2: consumer execute register2 = counter {register2 = 5}
S3: consumer execute register2 = register2 – 1 {register2 = 4}
S4: producer execute counter = register1 {counter = 6 }
S5: consumer execute counter = register2 {counter = 4}
9
PRODUCER/CONSUMER PROBLEM
(CONTINUES…)

• Considering that the first value of the counter


variable is 5, in the last case in the previous
example
• Its value incorrectly becomes 4.
• When the places of S4 and S5 change
• The value is again incorrectly becomes 6.
• The reason for this error is:
• Producer and consumer processes are allowed to update
the counter variable simultaneously.

10
RACE CONDITION

• If the read and write operations performed by two or


more processes on shared data have a final value
depending on which process executes when, this
situation is called a race condition.
• For example, to avoid the race condition in the
producer-consumer problem, it must be guaranteed
that only one process will change the counter
variable at a time. Processes must be synchronized in
some way.

11
EXAMPLE: PRINTER PROCESS
SPOOLER
Info:
• When the process wants to print a file, it writes the name of
the file into a special spooler array.
• The other process (printer daemon) constantly checks if there
is a file to print.
• If there are files, it prints them and removes their names from
the array.
• Let's assume that the Spooler array contains many entries.
• out: points to the next file to print.
• in: points to the next free slot in the array.

12
EXAMPLE: PRINTER PROCESS
SPOOLER ( C O N T I N U E S … )
Scenario:
• Processes A and B want to print a file. A reads in and stores 7 in the local variable.
• A clock interrupt occurs and the CPU thinks it has run process A long enough
and jumps to process B.
• B process reads the variable in and gets 7 again.
• In this case, they both think the next free slot is 7.
• B continues executing and writes the file name to slot 7 to print. It sets the in
variable to 8.
• When A will be executed from where it left off, it wants to write the file name to 7.
It deletes the filename added by B and writes its own filename.
• Printer daemon doesn't notice anything wrong, it continues working.
• B never gets an answer.

13
CRITICAL SECTION PROBLEM

• Suppose there are n processes in a system: {P0, P1, …, Pn-1}.


• Each process has a block of code called a critical region/section.
• Shared variables, a table or a file may be being modified in this
region.
• The parts of the program where processes access common data
areas and perform data reading and writing operations are
called critical regions/sections.
• Every process must ask for permission before entering its critical
section (entry section). After the critical section is completed,
the exit section follows. The remaining code is located in the
remainder section.

14
CRITICAL SECTION PROBLEM
(CONTINUES…)

15
CRITICAL SECTION PROBLEM
(CONTINUES…)

The solution to the critical section problem must meet 3


conditions.
1. Mutual Exclusion: If a process runs in a critical section, no
other process can run in the critical section.

16
CRITICAL SECTION PROBLEM
(CONTINUES…)

2. Progress: If no process is running in the critical section


and there are some processes that want to enter the
critical section, these processes enter the critical section
one by one. The desire to enter the critical section
cannot be postponed for a long time. In other words,
processes should not prevent each other from
executing tasks continuously. Mutual blockage should not be
caused.
3. Bounded Waiting: There is a limit to the number of
times other processes can enter the critical section while
a process is waiting. (No starvation)

17
CRITICAL SECTION PROBLEM
(CONTINUES…)

• Solutions
• Software
• Peterson Solution
• Hardware
• Mutex locks
• Semaphores

18
PETERSON SOLUTION

• It is a classical software-based solution developed for the


critical section problem.
• Peterson algorithm is designed for 2 processes. These
processes share 2 data objects and this is how they
synchronize.
• int turn: Determines the order of entering the critical section.
if turn==i then Pi can enter the critical section.
• boolean flag[2]: Indicates that a process is ready to enter the
critical part. if flag[i] is true then Pi is ready to enter its critical
part.

19
PETERSON SOLUTION (CONTINUES…)

20
PETERSON SOLUTION (CONTINUES…)

P0 code block P1 code block


flag[0] = true; flag[1] = true;
turn = 1; turn = 0;
while (flag[1] && turn == 1); while (flag[0] && turn == 0);
-------------- --------------
Critical_section_işini_yap(); Critical_section_işini_yap();
-------------- --------------
flag[0] = false; flag[1] = false;
-------------- --------------
Remainder_section_devam_et(); Remainder_section_devam_et();
• Even if both processes change the turn variable at the same time,
the last value is taken and that process enters the critical section
(mutual exclusion).
• The process that completes the critical section cancels the need to
enter the critical section and the other process enters the critical
section. (progress).
• Once a process enters the critical section, it passes the queue to21
another (bounded waiting).
MUTEX LOCKS

• Operating system designers have developed various


software tools (libraries or APIs) for the critical
section problem.
• The simplest software tool is the mutex lock
tool.
• Mutex lock is used to protect critical sections and
prevent race conditions.
• A process must request a lock before entering
its critical section.

22
MUTEX LOCKS (CONTINUES…)

• The lock variable should be released when the


critical section is left:
• Each process requests permission to enter and lock the
critical section (acquire()).
• After leaving the critical section, the lock status is
terminated (release()).
• A boolean variable is used to decide whether the lock state is
available.
• Since acquire and release function calls must be
atomic, hardware-based solutions are used in the
background of this function.
23
MUTEX LOCKS (CONTINUES…)

• In mutex locks, a thread/process owns the lock.


• When another thread requests this lock, it does not
spinlock, it is blocked and goes into sleep state. The
process state changes and the Context switch occurs.

24
PTHREAD MUTEX API FUNCTIONS

• pthread_mutex_t lock
• Defines the mutex object.
• pthread_mutex_init(&lock, NULL)
• Creates the mutex object.
• pthread_mutex_lock(&lock)
• Locks the critical section of code block.
• pthread_mutex_unlock(&lock)
• Unlocks the lock on the critical section code block.
• pthread_mutex_destroy(&lock)
• Terminate the mutex object.

25
SPINLOCK MECHANISM

• There are scenarios where the use of mutex may cause


performance problems (Context switch).
• For example, let's assume that threads A and B lock a mutex
resource, perform the operation very quickly and release the
lock, and do this thousands or hundreds of thousands of
times per second.
• Since mutex operations require context-switching, and the
locking time is very short, but after a while, the process of
the thread going into Sleep (waiting) state and then waking it up
again (ready) with each locking operation turns into a time-
consuming process.
• In such a case, it would be more advantageous to use
spinlock instead of using mutex.

26
SPINLOCK MECHANISM (CONTINUES…)

• Spinlock is performed in user mode with busy wait. Therefore, the


relevant thread does not go into Sleep mode, the context-switch
does not occur, and it can fully use the CPU time allocated to it in
user mode.
• However, if the relevant application continues to use the CPU and
cannot reach the spinlock it expects very quickly, this time it
will have the opposite effect, and if it goes into Sleep mode, while
another operation can be performed with the CPU in the same time
period, this opportunity is eliminated and causes the CPU load to
increase.
• Therefore, it would be wrong to say that using spinlock will give
better results in all scenarios.

27
SPINLOCK MECHANISM (CONTINUES…)

• The main problem with spinlocks is the busy waiting


cycle.
• While a process is in its critical section, other
processes that want to enter their critical sections are
constantly processed in the loop within the acquire()
function. They wait without doing anything else.
• Moreover:
• Since there is a busy wait, the waiting process also
consumes processor time.
• When a process exits its critical region, starvation may occur
if there are multiple processes waiting.
28
PTHREAD SPINLOCK API FUNCTIONS

• pthread_spinlock_t spinlock
• Defines the spinlock object.
• pthread_spin_init(&lock, NULL)
• Creates the spinlock object.
• pthread_spin_lock(&lock)
• Locks the critical section of code block.
• pthread_spin_unlock(&lock)
• Unlocks the lock on the critical section code block.
• pthread_spin_destroy(&lock)
• Terminate the Spinlock object.

29
SEMAPHORES

• It was described by Dijkstra in 1965.


• It is called generalized lock.
• They form the basic synchronization infrastructure of
the UNIX operating system.

30
SEMAPHORES (CONTINUES…)

• Semaphore S – is an integer variable


• It has two standard atomic operations
• S: | acquire() release() |
• Original representations P() and V()
• Proberen (to test) and Verhogen (to increment) in German
• Also down() and up()
• Also wait() and signal()

31
SEMAPHORES (CONTINUES…)

• wait() and Signal() definitions are given below.


• The value of S is decreased with wait(), and the
value of S is increased with signal().
• wait() and signal() operations on S are
performed without interruption.

32
SEMAPHORES (CONTINUES…)

• Operating systems uses two types of semaphores,


1. Counting semaphore
2. Binary semaphore
• The value of counting semaphores is not limited.
• Binary semaphores can have a value of 0 or 1.
• Binary semaphore acts like mutex locks.

33
SEMAPHORES (CONTINUES…)

• Counting semaphores are used to control access to a


specified number of resources.
• The counting semaphore is initialized with the resource
count.
• Each process that wants to use the resource performs a
wait() operation on the semaphore (the counter is
decremented).
• When a process releases the resource, it performs a
signal() operation (the counter is incremented).
• When semaphore value = 0, all resources are being
used. (occupied)
34
SEMAPHORES (CONTINUES…)

• Hotel example
• The hotel's receptionist uses the semaphore variable to give
rooms (resources) to customers (process/thread).
• The number of rooms available in the hotel when the hotel
is completely empty (S = number of rooms in the hotel). The
number of rooms is reduced as customers arrive.
• This number is increased when leaving the room. When the
number reaches zero, there is no room left and those who
come can wait in the lobby (queue) if they want. Those
waiting are taken in order (FIFO).
• In a binary semaphore, there is only one room.

35
SEMAPHORE IMPLEMENTATION

• The use of wait() and signal() functions, such as a


mutex lock, is similar to previous approaches to
solving the critical section problem. For example: A
process executes wait() and waits if it finds that the
value of the semaphore is not positive.
• In other words, using semaphore in this form will cause
a busy waiting situation and waste CPU.
• To solve the busy waiting problem
• Instead of keeping the process busy on the CPU,
• The process should be blocked and placed in the
waiting queue.

36
SEMAPHORE IMPLEMENTATION
(CONTINUES…)

• In this implementation, the process blocks itself instead of busy


waiting. The blocked process is associated with the semaphore, its
status is set to “waiting”, and it is placed into a waiting queue
associated with the semaphore.
• The blocked process waiting on semaphore S can be restarted
(ready queue) when some of the other processes execute the signal
operation.
• The process is restarted with a wakeup() operation. This switches
the status of the process from waiting è ready. (running depends
on CPU scheduling)
• There are 2 operations (system calls) used by the kernel:
• block()
• Changes the status of the process from running è waiting.
• Places the process in the waiting queue.
• wakeup()
• It removes 1 process associated with the semaphore from the waiting
queue and puts it in the ready queue.

37
SEMAPHORE IMPLEMENTATION
(CONTINUES…)

• Each semaphore has an integer value and a list of


processes waiting on that semaphore.
• If a process must wait on a semaphore, it is added to the
semaphore's process list. (block system call is called)
• The signal operation removes the process from the semaphore
list. (wakeup system call is called)
38
SEMAPHORE IMPLEMENTATION
(CONTINUES…)

wait()

signal()

39
CLASSIC SYNCHRONIZATION
PROBLEMS

• Three classical synchronization problems will be


discussed.
1. The Bounded-Buffer Problem
2. The Readers–Writers Problem
3. The Dining-Philosophers Problem

40
REFERENCES

• Textbook:
• Operating System Concepts, Ninth Edition, Abraham
Silberschatz, Peter Bear Galvin, Greg Gagne
• http://www.albahari.com/threading/

41

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy