0% found this document useful (0 votes)
23 views51 pages

05 - Process Synchronisation Part 2

The document discusses different mechanisms for implementing mutual exclusion in critical sections, including semaphores, monitors, and messages. It focuses on semaphores and monitors, explaining what they are, how they work, and provides examples of using them to solve the producer-consumer problem.

Uploaded by

milton21207613
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)
23 views51 pages

05 - Process Synchronisation Part 2

The document discusses different mechanisms for implementing mutual exclusion in critical sections, including semaphores, monitors, and messages. It focuses on semaphores and monitors, explaining what they are, how they work, and provides examples of using them to solve the producer-consumer problem.

Uploaded by

milton21207613
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/ 51

Process Synchronisation – Part 2/2

Lecture 5

Soumyabrata DEV
https://soumyabrata.dev/
Implementations

There are three basic mechanisms for implementing mutual


exclusion in critical sections

1. Semaphores
• Simple, but hard to program with
• Very low level

2. Monitors
• Higher level mechanism
• Requires higher-level programming languages

3. Messages
• Synchronisation without shared memory
• Uses Interprocess Communication (IPC) messages instead
2
Semaphores

3
Semaphore

• Semaphores are a fundamental synchronization mechanism in


operating systems and concurrent programming.
• Semaphores are synchronization primitives used to manage access to
shared resources and coordinate the execution of multiple processes
or threads in a concurrent environment.

4
Semaphore

• Semaphore is simply a variable which is non-negative and shared


between threads.
• This variable is used to solve the critical section problem and to
achieve process synchronization in the multiprocessing environment.

5
Semaphore

Semaphores are of two types:


• Binary Semaphore – This is also known as mutex lock. It can have
only two values – 0 and 1. Its value is initialized to 1. It is used to
implement the solution of critical section problem with multiple
processes.
• Counting Semaphore – Its value can range over an unrestricted
domain. It is used to control access to a resource that has multiple
instances.

6
Binary Semaphore

• A binary semaphore, also known as a mutex (short for mutual


exclusion), has two possible values: 0 and 1.
• It is often used to protect critical sections of code or shared
resources.
• When a process or thread acquires a binary semaphore, it sets it to 1
(indicating that the resource is locked). If the semaphore is already 1,
subsequent attempts to acquire it will block until it is released (reset
to 0) by the owning entity.

7
Counting Semaphore

• A counting semaphore can have values greater than 1, typically


representing the number of available instances of a resource.
• It is used for scenarios where multiple processes or threads can
access a shared resource concurrently, up to a specified limit.
• When a process or thread acquires a counting semaphore, the
semaphore's value decreases. When it releases the semaphore, the
value increases.

8
Semaphore Operations

Semaphore operations typically include:

• Wait (P) Operation: Decrements the semaphore value. If the value


becomes negative, the process or thread is blocked until the
semaphore becomes non-negative.
• Signal (V) Operation: Increments the semaphore value. If any
processes or threads were waiting, one of them is unblocked.

9
Semaphore

A semaphore S is an integer variable that can be accessed only through


two standard operations : wait() and signal().

The wait() operation reduces the value of semaphore by 1 and the


signal() operation increases its value by 1.

wait(S){
while(S<=0); // busy waiting
S--;
}

signal(S){
S++;
}
10
The Producer/Consumer Problem

• This is a common synchronisation problem

• Consider a producer process supplying a resource


to a consumer process
• Producer: creates instances of a resource
• Consumer: uses up instances of a resource

11
The Producer/Consumer Problem

• Producer and consumer share a buffer


• The producer put resources into the buffer

• The consumer takes resources from the buffer

• The buffer has a finite size

12
Problem Constraints

• The consumer must wait for producer if the buffer


is empty

• Producer must wait for consumer if the buffer is full

13
Synchronisation

• We need to keep the producer and consumer


synchronised

• The buffer is the critical section in this problem

• We usually need mutually exclusive access to the buffer

14
P/C Solution with Semaphores

Initialization of semaphores

mutex = 1

Full = 0 // Initially, all slots are empty. Thus


full slots are 0

Empty = n // All slots are empty initially

15
P/C Solution with Semaphores
Solution for Producer

do{

//produce an item Explanation:

When producer produces an item then the


wait(empty);
value of “empty” is reduced by 1 because
wait(mutex); one slot will be filled now. The value of
mutex is also reduced to prevent consumer
//place in buffer to access the buffer. Now, the producer has
placed the item and thus the value of “full”
signal(mutex); is increased by 1. The value of mutex is
signal(full); also increased by 1 because the task of
producer has been completed and
}while(true) consumer can access the buffer.

16
P/C Solution with Semaphores
Solution for Consumer

do{

wait(full); Explanation:
wait(mutex);
As the consumer is removing an item from
buffer, therefore the value of “full” is
// remove item from reduced by 1 and the value is mutex is also
buffer reduced so that the producer cannot
access the buffer at this moment. Now, the
signal(mutex); consumer has consumed the item, thus
signal(empty); increasing the value of “empty” by 1. The
value of mutex is also increased so that
// consumes item producer can access the buffer now.

}while(true)
17
Monitors

18
The Problem with Semaphores

• Semaphores are nice but they have an important


problem

• Using more than one semaphore can lead to deadlocks, if


order of wait() and signal() are not correctly set

• It is difficult to program with semaphores

Deadlocks are where processes or threads are stuck


waiting for resources that will never become available.
19
Monitors

• Monitors are higher-level sync primitives

• A monitor is a collection of procedures, variables and


data grouped together in a special kind of structure

• Their aim is to avoid the problems that can arise when


protecting critical sections with semaphores

20
Monitors

• Monitors are a synchronization mechanism that


encapsulates both data and the procedures (methods)
that operate on that data within a single programming
construct.

Basic Structure of a Monitor

A monitor typically consists of:


• Shared data: Variables that represent the shared resource or state.
• Procedures (methods): Operations that can be performed on the shared
data.
• Condition variables: Used for signaling and waiting within the monitor.

21
Example Monitor

monitor example {
int i; (Internal data)
condition c; (Condition variable)

void p() { (Monitor procedure)


...
}
}
22
Monitor Rules

• Processes may call monitor procedures whenever they wish

• Processes can’t access internal monitor data (variables, etc.) using


external procedures

23
Monitor Rules

• Only one process can be active inside a monitor

• Mutual exclusion inside the monitor is guaranteed by the compiler

24
Blocking in Monitors

• Mutual Exclusion is implemented using internal condition variables

• Conditions have two operations


• Wait
• Signal

25
wait(condition)

• This is executed when the monitor discovers that a process cannot


proceed
• The monitor blocks a process calling wait() and makes it wait on condition
• Another process can then be allowed into the monitor
• A process that calls wait() is always blocked

26
signal(condition)

• This is executed to wake up a process that is waiting


on condition

• After executing signal() the calling process must exit


the monitor immediately
• This guarantees mutual exclusion

27
Monitor for Producer/Consumer

• Requires two conditions:


• Buffer is full
• Buffer is empty

• Requires some internal data so we know when it is


empty or full

28
Monitor for Producer/Consumer

• Requires two operations


• Put a message in the buffer
• Remove a message from the buffer

29
Producer and Consumer Code

• Simplest possible consumer and producer code

• Monitor takes care of any issues, not producer or consumer

30
Benefits of Monitors

• Abstraction: Monitors provide an abstract and structured way to


handle synchronization, reducing the complexity of concurrent
programming.
• Safety: They help prevent common synchronization errors like data
races and deadlocks.
• Encapsulation: The encapsulation of data and procedures within a
monitor promotes clean and modular code design.

31
Drawbacks of Monitors

• Monitors are a high-level abstraction and may not be suitable for all
types of concurrent applications, especially in low-level or embedded
systems.
• Proper use of monitors requires understanding and adhering to
monitor-specific programming practices.

32
Messages

33
Messages System

Messages in operating systems refer to a mechanism used for


interprocess communication (IPC), allowing different processes or
threads to exchange data, request services, and synchronize their
activities within a computer system.

Message Components

A message typically consists of two main components:


• Message Header: Contains metadata about the message, including
the sender's identity, the recipient's identity, message type, and
other control information.
• Message Body: Carries the actual data or payload of the message,
which can be of various types, such as commands, requests,
responses, or simple data.

34
Messages System

• Synchronisation with both semaphores and monitors relies on shared


memory
• The message system is a mechanism for inter-process communication
(IPC), that can also be relied upon for synchronisation without having
to share memory

35
Message System

• Elements in the message system:


• message: information that can be exchanged between two (or more)
processes or threads
• mailbox: a place where messages are stored between the time they are sent
and the time they are received

36
Message System Scheme
m Scheme
• Process A sends messages to process B using a mailbox

sends messages to process B using a mail


messages
send receive

A B
mailbox
a pipe can be implemented with messages 37
Message System Scheme

• One process or the other owns the data


• Never two at the same time

• If processes need to send messages both ways, we need two


mailboxes

38
Message System Operations

• Two basic operations


• send(mailbox, message)
• Put a message in the mailbox
• receive(mailbox, message)
• Remove a message from the mailbox
• In practice we also need the system calls create(mailbox) and
delete(mailbox)

39
Message System Addressing

• The message identifies source and destination


processes
• Through their PIDs

• There may be multiple destinations, or destination


may be unspecified

40
Message Format

• Depends on the objectives of the system

• fixed-length: minimise processing and storage overhead

• variable-length: more flexible approach for operating


systems

41
Why Use Messages?

• Communicating processes sometimes need to be


separate
• They do not trust each other
• The programs were written at different times by different
programmers who knew nothing about each other
• They run on different processors
• Less error-prone without shared memory

42
Mutual Exclusion with Messages

• Mutual exclusion must be guaranteed solely relying


on the mailbox

• Two levels of synchronisation in a message system

• Producer/Consumer Constraints
• Execution flow constraints

43
Producer/Consumer Constraints

• receive()
• Calling process waits when the mailbox is empty until a
message is added

• send()
• Calling process waits when mailbox is full until there is
space for another message

44
Execution Flow Constraints

• Send and receive: could be blocking or non-blocking

• Blocking send: when a process sends a message it blocks


until the message is received at the destination.

• Non-blocking send: After sending a message the sender


continues with its processing without waiting for it to
reach the destination

45
Execution Flow Constraints

• Send and receive: could be blocking or non-blocking

• Blocking receive: When a process executes a receive it


waits blocked until the receive is completed and the
required message is received

• Non-blocking receive: The process executing the receive


proceeds without waiting for the message

46
Execution Flow Constraints

• The most common combination is that of

• Blocking Receive
• Non-blocking send

47
Mutual Exclusion using Messages

• Mutual exclusion can be achieved using a single shared mailbox

• Processes can enter the critical section whenever they receive a


message

• Whenever they leave the critical section they must send a new
message to the mailbox

48
Producer/Consumer Algorithm Using Messages

• Not only we need to ensure mutual exclusion but


also to keep a count

• For this two mailboxes are needed


• one mailbox for consumers: data produced and consumed
• one mailbox for producers: accountancy purposes

49
Producer/Consumer Algorithm Using Messages

• Producers generate data and send it to the


consumers's mailbox
• Only when the producer’s mailbox indicates there is at
least one free slot in the buffer

• Consumers take messages from the consumer’s


mailbox when available
• Then send empty messages to the producer’s mailbox to
signal new free slot

50
Thank you!

See you next class!


25 September, Monday, 9:55am to 11:30am, TB3-105

51

You might also like