Process Management - Lesson 5 - Concurrency-1
Process Management - Lesson 5 - Concurrency-1
Process Management - Lesson 5 - Concurrency-1
Concurrency
Concurrency is the interleaving of processes in time to give the appearance of simultaneous execution.
It is achieved by interleaving operation of processes on the processor, which creates the illusion that
these processes are operating at the same time. Concurrency in multiprogramming operating systems
involves communication among processes, sharing of and competing for resources, synchronization of
activities of multiple processes and allocation of processors time to process.
Need/importance of concurrency
Interleaving operations of processes on the processor in multiprogramming operating systems is
important or necessary due to the following reasons:
The operating system must be able to keep truck of the various active processes. This is done
with the use of Process Control Block (PCB).
The operating system must allocate and deallocate various resources for each active process.
These resources include processor time, memory, file, I/O devices etc.
The operating system protects the data and physical resources of each process against
unintended interference by other processes.
The results of a process must be independent of the speed of which the execution is Processes
of an application need to interact with one another because they work towards a common goal.
Concurrent processes
Processes that coexist in the memory at some time are called concurrent processes.
Types of concurrent processes
Processes executing concurrently in the operating system may be of two types:
Independent processes or competitors: These are processes whose execution cannot affect or
be affected by the execution of other processes. They do not share any kind of information or
data with each other. They just compete for resources such as the processor, and I/O devices that
are required to accomplish their operations.
Cooperating or interacting processes: These are processes whose execution affect or is
affected by the execution of other processes and share data with other processes. They need to
exchange data or information with each other.
it has acquired the other source and performed the function requiring both resources. The two
processes are said to be deadlocked.
Starvation: Suppose that three concurrent processes (P1, P2, and P3) each require periodic access
to resource R. Consider the situation in which P1 is in possession of the resource and both P2 and
P3 are delayed, waiting for that resource. When P1 exits its critical section, either P2 or P3 should
be allowed access to R. Assume that the operating system grants access to P3 and that P1 again
requires access to R before P3 completes its critical section. If the operating system grants access
to P1 and P3, then P2 may be indefinitely denied access to the resource, even though there is no
deadlock situation.
Forms of process cooperation
In general, there are two primary forms of explicitly process interaction and they include:
Interprocess communication: This is the passing of information cooperating processes for such
purposes as exchanging data reporting progress and accumulating collective results.
Interprocess synchronization: This is the sharing of system resources by concurrent process in
such a way that, concurrent access to shared data is handled thereby minimizing the chance of
inconsistent data.
Interprocess synchronization
Interprocess synchronization, also known as process synchronization or process coordination, is the
coordination of process activities to ensure that actions are performed in a desired order and a common
objective is achieved. Coordination is achieved through a process seeking the consent of some other
processes before performing a sensitive action ai, these processes give consent only if they have
performed all actions which are supposed to proceed action ai, and thus coordination is achieved.
Synchronization among cooperating concurrent process is essential for preserving precedence
relationships and for preventing concurrently related timing problems. Cooperating processes must
synchronize with each other when they are to share resources.
Process synchronization involves use of critical sections or indivisible signalling operations. Each of
these is implemented by using a lock variable that has only two possible values open (0) and closed
(1). A process cannot begin execution of a critical section or an indivisible operation if the lock
variable associated with the critical section or indivisible operation has the value closed. If it finds the
value of the lock variable to be open, it changes the value to closed, executes the critical section or
indivisible signaling operation, and changes the value back to open. A process that finds the value of a
lock variable to be closed must wait until the value is changed to open. We refer to this arrangement
involving use of a lock variable as a synchronization lock, or simply a lock, and refer to the actions of
closing and opening the lock as setting and resetting it.
Types of synchronization locks
Queued lock: A process waiting for a queued lock becomes blocked and its id is entered into a
queue of processes waiting for the lock. The process is activated when the lock is reset and it is
the first process in the queue.
Spin lock: This is a mutual exclusion mechanism in which a process executes in an infinite loop
waiting for the value of a lock variable to indicate availability. If a spin lock is already set when
a process tries to set it, the process enters into a busy wait for the lock. The CPU on which the
process is operating can handle interrupts during the busy wait.
Sleep lock: When a process waits for a sleep lock, the CPU on which it is running is put into a
special sleep state in which it does not execute instructions or process interrupts. The CPU is
activated when the CPU that resets the lock sends it an inter processor interrupt.
Race condition
A race condition is a condition that occurs when multiple concurrent processes or threads read and
write (access and manipulate) the same data concurrently and the final result depends on the particular
order in which the access takes place.
Example
Suppose that two processes, P1 and P2 share a global variable a, at some point in it execution, P1
updates x to the value 1 and at some point in its execution P2 updates x to the value 2. Thus, the two
tasks are in a race to write variable x. In this example the ‘loser” of the race (the process that updates
the variable x, last) determines the final value of x. A solution to race conditions
Classical problems of process synchronization
Process synchronization was introduced as an operating system operation in process management, to
handle the problems that arose during the execution of multiple concurrent processes and sharing of
resources by cooperating processes. These problems include:
Critical section problem
Scenario
A critical section is a code segment that can be accessed by only one process at a time. It is a section
of code in which a process accesses shared resources. The execution of critical sections by concurrent
processes is mutually exclusive i.e. only one process can be in its critical section at any given time.
Each process request permission to enter its critical section and must wait unit the first one finishes. A
critical section protocol consist of two parts namely:
An entry section
An exit section
Between them is the critical section that must run in a mutually exclusive way.
Problem
Two processes could enter their critical sections at the same time.
Solution
A solution to the critical section problem is to find some way to prohibit more than one process from
reading and writing the shared data at the same time i.e. mutual exclusion. Mutual exclusion is the
requirement that one process never enters it critical section at the same time that another concurrent
processes enters its own critical section.
Requirements for mutual exclusion
A solution to the critical section problem must satisfy the following three requirements:
Mutual exclusion: Mutual exclusion must be enforced; only one process at a time is allowed
into its critical section among all processes that have critical sections for the same resource or
shared object. No two processes may be simultaneously inside their critical section.
Progress: When no process is in a critical section any process that requests entry to its critical
section must be permitted to enter without delay.
Bounded waiting: No process should have to wait forever to enter its critical region. It must not
be possible for a process requiring access to its critical section to be delayed indefinitely, no
deadlock or starvation.
Bound buffer problem
Scenario
Bounded buffer problem also known as producer and consumer problem is a process synchronization
problem where there is a buffer or circular queue of n slots (finite size) and each slot is capable of storing
one unit of data. It also has two pointers “in” and ‘out” and two running processes namely producer
and consumer which are operating the buffer.
Two types of buffers can be used, namely
Unbounded buffer: This type of buffer places no practical limit on the size of the buffer. The
consumer may have to wait for new items, but the producer can always produce new items.
Bounded buffer: This type of buffer assumes a fixed buffer size. In this case, the consumer
must wait if the buffer is empty, and the producer must wait if the buffer is full.
A producer process produces data items (records, characters) and tries to insert them into an empty slot
of the buffer using the ‘in” pointer. The consumer process removes data items from a filed slot in the
buffer one at a time using the “out” pointer.
Problem
The producer process may try to add data items into the buffer if full and the consumer process trying
to remove data items from an empty buffer.
Solution
Producer consumer problem can be solved using semaphores or monitors. The operating system must
maintain count of empty and full buffer slots and there has to be synchronization between the producer
process and the consumer process so as to avoid the producer process trying to add data items into the
buffer if full and the consumer process trying to remove data items from an empty buffer this is achieved
by using semaphores, there are three semaphores namely:-
Full: This is a counting semaphore which counts the number of full slots in the buffer at any
given instant.it represents the number of occupied slots in the buffer and its initial value is 0
Empty: This is a counting semaphore which counts the number of empty slots in a buffer at any
instant. It represents the number of empty slots in the buffer and its initial value is the number
of slots in the buffer since initially all slots are empty.
Mutex (m): This is a semaphore used to enforce mutual exclusion. It ensures that only one
process either producer or consumer may access the buffer at any given instant and is initialized
to the value 1.
Hence;
The structure of a producer process will be as follows
Note: Mutual exclusion is enforced by a Mutex semaphore, synchronization is enforced using ‘full”
and ‘empty” semaphores that avoid race condition and deadlock in the system. If the above three
semaphores are not used there will be a race condition or deadlock situation as well as loss of data
Read and write problem
Scenario
This is a synchronization problem where there is a shared resource which should be accessed by
multiple processes. There are two types of processes in this context namely;
Readers: These are a number of processes that only read (view) content from the shared
resource.
Writers: These are a number of processes that write (add) content into the shared resource.
Problem
Since there is a resource being shared, then readers and writers can create conflict due to these
combinations: Writer - writer and write - reader access to critical section simultaneously that creates
synchronization problem, loss of data e.tc. i.e.
A reader can be kept waiting for other readers to finish simply because a writer is waiting thus
starving the reader
A reader may read the shared file(shared object) while the writer writes
Solution
Semaphores are used as a solution to the reader writer problem and the following conditions must be
satisfied:
Any number of readers may simultaneously read from the shared resource (enter the critical
section).
Only one writer may write to the shared resource (enter the critical section) at a time.
When a write is writing data to the shared resource (inside the critical section), no other process
can access the resource (enter the critical section).
A writer cannot write to the resource, if there are non-zero number of readers accessing the
resource (in the critical section)
The following semaphore are used
Mutex: This semaphore is initialized to 1 and is used to ensure mutual exclusion when the
variable read count is updated.
Read_count: This semaphore is initialized to zero and keeps track of how many processes are
currently reading or accessing the shared object.
Rw_mutex: This semaphore is also initialized to 1 and is common to both reader and writer
processes. It functions as a mutual exclusion semaphore for the writers and is also used by the
first or last reader that enters or exits the critical section as locks.
Note: If a writer is in the critical section and n readers are waiting, then one reader is queued on
rw_mutex, and n − 1 readers are queued on mutex. Also observe that, when a writer executes signal
(rw_mutex), we may resume the execution of either the waiting readers or a single waiting writer
The dining philosopher’s problem
Scenario
This is a process synchronization problem that involves the allocation of limited resources from a group
of processes in a deadlock free and starvation free manner. Five philosophers live in a house, where a
table is laid for them. The life of each philosopher consists principally of thinking and eating and through
years of thought, all philosophers had agreed that only food that contributed to their thinking efforts was
spaghetti. Due to a lack of manual skill, each philosopher (processes) requires two forks (resources) to
eat spaghetti. The eating arrangement are simple, a round table on which is set a large serving bowl of
spaghetti, five plates, five forks, one for each philosopher and the five philosophers sit around the round
table.
Only one fork is available between each philosopher, at any instant a philosopher is either eating or
thinking. When a philosopher wants to eat, he picks up first the fork on the left and then the fork on the
right. When the philosopher is finished eating and he wants to think he puts down both forks at their
original places.
Problem
Philosophers may starve, if all philosophers are hungry at the same time, they will all pick up
the fork on their left and they all reach out for the other fork, which is not there thus all
philosophers will starve.
Two philosophers can use the same fork at the same time.
Solution
The dining philosophers problem can be solved by an algorithm which implements semaphore and
monitors that ensure maximum number of philosophers can eat at once and none starves as long as each
philosopher eventually stop eating and it must satisfy the following conditions.
It must allow a philosopher to pick up the fork only if both the left and right fork are available.
It must allow only four philosophers to sit at the table, with at most four seated philosophers at
least one philosopher will have access to two forks.
One simple solution is to represent each chopstick with a semaphore. A philosopher tries to grab a
chopstick by executing a wait () operation on that semaphore. She releases her chopsticks by executing
the signal () operation on the appropriate semaphores.
Although this solution guarantees that no two neighbors are eating simultaneously, it nevertheless
must be rejected because it could create a deadlock. Suppose that all five philosophers become hungry
at the same time and each grabs the left chopstick. All the elements of chopstick will now be equal to
0. When each philosopher tries to grab the right chopstick, the philosopher will be delayed forever.
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.
A solution to the dining-philosophers problem that ensures freedom from deadlocks is use of mutex
locks.
Note: Any satisfactory solution to the dining-philosophers problem must guard against the possibility
that one of the philosophers will starve to death. A deadlock-free solution does not necessarily
eliminate the possibility of starvation.
The sleeping barber problem
Scenario
This is a process synchronization problem that assumes that a barber shop has one barber, one barber
chair and n chairs for waiting customers, if any to sit on if there are no customer preset. The barber sits
down in the barber’s chair and falls asleep.
When a customer arrives, he has to wake up the sleeping barber. If additional customers arrive while the
barber is cutting a customer’s hair, they either sit down if there are empty chairs) or leave the shop (if
all chairs are full).
Problem
The barber and customers could get into a race condition.
Solution
The sleeping barber problem can be solved using three semaphores namely:
Customers: This is a counting semaphore which counts waiting customer (exchanging the
customer in the barber’s chair, who is not waiting) and whose initial value is zero.
Barber: This is a counting semaphore which counts of barbers who are idle, waiting for
customers and whose initial value is zero.
Mutex: This is a semaphore used to enforce mutual exclusion and whose initial value is one.
There is need for a variable waiting which counts the number of waiting customer. This variable
is a copy of the customer semaphores since there is no way to read the current value of the
customer semaphore.
Mutual exclusion can be achieving in various ways so that while one process is busy updating memory
in its critical section. Another process will enter its critical section and cause trouble. These approaches
are divided into three categories namely;
Software solutions
Hardware solutions
Operating systems solutions
Software solutions
These are mechanisms for enforcing mutual exclusion that use global variables to control access to the
critical section and take the form of algorithms whose correctness does not rely on any other
assumptions and examples include:
Strict alternation or turn variable or Dekker’s algorithm
This algorithm enforces mutual exclusion by allowing only one process into the critical section at a time
i.e. If one process is already in its critical section, then the other will have to wait. Strict alteration
satisfies mutual exclusion and bounded waiting (no saturation) but does not satisfy progress it also
avoids deadlock. Note: Dekker’s algorithm was later Peterson and came to be known as Peterson’s
Algorithm.
Peterson’s Algorithm
Peterson’s solution is restricted to two processes that alternate execution between their critical sections
and remainder sections. The processes are numbered P0 and P1. Peterson’s solution requires the two
processes to share two data items namely;
int turn: The variable turn indicates whose turn it is to enter its critical section. That is, if
turn = = i, then process Pi is allowed to execute in its critical section.
boolean flag[2]: The flag array is used to indicate if a process is ready to enter its critical
section. For example, if flag[i] is true, this value indicates that Pi is ready to enter its critical
section.
To enter the critical section, process Pi first sets flag[i] to be true and then sets turn to the value j,
thereby asserting that if the other process wishes to enter the critical section, it can do so. If both
processes try to enter at the same time, turn will be set to both i and j at roughly the same time. Only
one of these assignments will last; the other will occur but will be overwritten immediately. The
eventual value of turn determines which of the two processes is allowed to enter its critical section
first.
Barkley’s algorithm
This algorithm enforces mutual exclusion by use of numbers. Each process receives a number before
entering its critical section and the holder of the smallest number enters the critical section. If process Pi
and Pj receive the same numbers, then Pi is served first. Bakery algorithm satisfies mutual exclusion
progress and bounded waiting (no starvation). It also avoids deadlocks.
Lock variables
This algorithm uses a shared variable to enforce mutual exclusion. The shared variable is initialized to
zero and when a process wants to enter its critical section it first tests the shared variables, if the shared
variables value is zero the process locks (sets it to 1) the shared variable and enters the critical section.
After the shared variable has been locked, the processes desiring to enter their critical sections go into
busy waiting mode. Note: The term busy waiting or spin waiting refers to a technique in which a
process can do nothing until it gets permission to enter its critical section but continues to execute an
instruction or set of instruction that tests the appropriate variable to gain entrance. When a [process
leaves its critical section, it resets the lock to 0, at this point one and only one of the waiting process is
granted access to its critical section.
Disadvantages of software solutions
Processes that are requesting to enter in their critical section are busy waiting.
Hardware solutions
These are mechanisms for enforcing mutual exclusion which depend on machine instructions. All
these solutions are based on the premise of locking, i.e. protecting critical regions through the use of
locks. They include:
Test and set lock (TSL)
In this approach a shared variable which takes either of two values, 0 or 1 is used to enforce mutual
exclusion. A process inquires (tests) the share variable before entering its critical section. If the shared
variable is locked (value set to 1), it keeps on waiting until the shared variable becomes free
(unlocked), if the shared variables is unlocked (value set to) then the process takes it and locks it.
Note: The above instructions executed atomically, i.e. without interruption
Compare and swap
In this approach a process compares the contents of a memory location with a given value and only if
they are the same, modifies the content of that memory location to a new given value. The entire compare
and swap function is carried out automatically i.e. it is not subject to interrupt .The atomicity guarantees
that the new value is calculated based on up-to-date information. If the value had been update by anther
process than the write fails.
Mutex Locks
This approach enforces mutual exclusion by use of a shared variable known as a Mutex lock. A
process must acquire the lock before entering a critical section; it releases the lock when it exits the
critical section. A process wishing to enter its critical section, test the Mutex and if its value is 0
(unlocked), the process locks it (set value to 1). As the resource is locked while a process executes its
critical section no other process can access it. The process currently in its critical section must unlock
(set value to 0) the Mutex upon leaving the critical section. The acquire () function acquires the lock,
and the release () function releases the lock, as illustrated
Note:
Calls to either acquire () or release () must be performed atomically.
The main disadvantage of the implementation mutual exclusion using mutex locks 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.
Sleep and wake
This approach uses two primitives (variables), sleep and wake to enforce mutual exclusion. If the critical
section is not empty then the process desiring to enter the critical section will go to sleep by invoking
the sleep variable and is blocked. The blocked process is not scheduled to run again until another process
uses the wakeup primitive when leaving its critical section as shown in the algorithm below
Note: This approach is a solution to the wastage of processor time by processes waiting (busy waiting)
to enter their critical sections. Busy waiting processes waste processor time checking to see if they can
proceed (enter critical section).
Disabling Interrupts
This approach enforces mutual exclusion by allowing processes to disable all interrupts just after
entering their critical section and re-enable them before leaving it. With interrupts disabled, no clock
interrupts can occur. The processor is only switched from process to process as a result of clock or other
interrupts hence with interrupts turned off the processor will be switched to another process.
Note: The block () operation suspends the process that invokes it.
When a process releases a resource, it performs a signal () operation (incrementing the count). When
the count for the semaphore goes to 0, all resources are being used. After that, processes that wish to
use a resource will block until the count becomes greater than 0. The signal () semaphore operation
can be defined as
Note:
The block () operation suspends the process that invokes it.
The wakeup (P) operation resumes the execution of a blocked process P.
The block () and wakeup (P) operation are provided by the operating system as basic system
calls.
Binary semaphores
This is an integer variable whose value can range only between 0 and 1 during program execution.
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 have the following drawbacks:
Monitors
Although semaphores provide a convenient and effective mechanism for process synchronization,
their incorrect use can result in timing errors that are difficult to detect, since these errors happen only
if some particular execution sequences take place, and these sequences do not always occur.
To deal with such errors, researchers have developed high-level language constructs e.g. monitors. A
monitor is a high-level synchronization construct or primitive that provides equivalent functionality to
that of semaphores and that is easier to control. It used to solve errors that occur from incorrect use of
semaphores.
Interprocess communication
Cooperating processes require some mechanism to exchange data or pass information to each other.
One such mechanism is Interprocess communication (IPC). Interprocess communication is the
exchange of information between cooperating processes for such purposes as exchanging data,
reporting progress and accumulating collective results.
Models of Interprocess communication
There are two fundamental models of Interprocess communication namely:
Shared memory: In this model, a part of memory is shared among the cooperating processes
is established. The processes that need to exchange data or information can do so by writing to
and reading from this shared memory.
Message passing: In this model, the cooperating processes communicate by sending and
receiving messages to and from each other.
Note: Communication using message passing is much more time consuming as compared to shared
memory. This is because the message passing system is implemented with the help of operating
system calls and thus, it requires a major involvement of the kernel. On other hand, in shared memory
systems, system calls are used only to set up the shared memory area. Once the shared area is set up,
no further kernel intervention is required.
Interprocess communication (IPC) mechanism
During communication cooperating processes require an Interprocess communication mechanism that
will allow them to exchange data and information. There are a variety of mechanisms for Interprocess
communication and synchronization namely:
Pipes
Semaphores
Signals
Event counters
Shared memory
Message passing (messages)
Remote communication mechanisms
Socket
Remote Procedure Call (RPC)
Remote Method Invocation (RMI)
Equivalent of primitives
Pipes (shared files)
A pipe is a circular buffer allowing two processes to communicate. There are two common types of
pipes used in modern operating systems namely:
Ordinary pipes: Ordinary pipes allow two processes to communicate in standard producer
consumer fashion: the producer writes to one end of the pipe (the write-end) and the consumer
reads from the other end (the read-end). As a result, ordinary pipes are unidirectional, allowing
only one-way communication. If two-way communication is required, two pipes must be used,
with each pipe sending data in a different direction. Ordinary pipes provide a simple
mechanism for allowing a pair of processes to communicate. However, they exist only while
the processes are communicating with one another i.e. once the processes have finished
communicating and have terminated, the ordinary pipe ceases to exist.
Named pipes (FIFOs): Named pipes provide a much more powerful communication tool.
Communication can be bidirectional. Once a named pipe is established, several processes can
use it for communication. Additionally, named pipes continue to exist after communicating
processes have finished.
Semaphores
Semaphores are integer variables used in solving problems associated with synchronization and avoiding
race conditions during sharing.
Signals
A signal is a software interrupt that notifies a process that an event has occurred. When a signal is sent
to a process, the operating system interrupts the process’s flow of execution.
Event counters
An event counter is a special variable used by processes to access resources. Like a semaphore, it has
an integer count and a set of waiting process identifications but unlike semaphores, the count variable
only increases. An event counter E has the following three operations defined;
Read (E): Return the current value of E.
Advance (E): Atomically increment E by1.
Await (E, v): Wait until E has a value of v or more.
Before a process can have access to a resource, it first reads E, if value is good, advance E otherwise await
until v reached.
Shared memory
In shared memory systems, the process that needs to communicate with the other processes created a
shared memory segment in its own address space. Other processes can communicate with this process
attaching its shared memory segment along with their address space. All the communicating processes
can read or write data through this shared area as shown in the diagram below
Assuming that process P1 is a producer process and process P2 is a consumer process, these two
processes need to run concurrently thereby requiring communication with each other. Both the
producer and consumer processes are made buffer (temporal queue) between them. The producer
process, P1 fills the buffer (temporal queue) by placing the produced items in it and the consumer
process, P2 empties the buffer (temporal queue) by consuming these items.
Message passing (messages)
In message passing systems, two system calls, send () and receive (), are used. The sender process, P1
send the message to the operating system invoking the send () system call. The operating system stores
this message in the message buffer area until the receive () system call is invoked by the receiver
process, P2. After the operating system delivers this message to P2. In case there is no message
available for P2 when it invokes the receive () system call, the operating system blocks it until some
messages arrives for it. On the other hand, if a number of messages arrive for P2, the operating system
puts them in a queue and delivers them in FIFO order upon the invocation of receive () call (one for
each process) by P2 as shown in the diagram below
In message passing, it is not necessary for the communication processes to reside on the same
computer rather they may reside on different computers connected via a network (a distributed
environment). Therefore, whenever two processes want to communicate, a communication link must
be established between them.
Types of communication
Process may communicate with each other in four ways:
Directly
Indirectly
Synchronous
Asynchronous
Direct communication
In direct communication, processes address each other by their PID assigned to them by the operating
system, e.g., if a process P1 wants to send a message to process P2, then the system calls send () and
receive () will be defined as follows
send(PID2, message)
receive(PID1, message)
since both sender and receiver process need to know each other’s PID, this type of communication is
known as symmetric direct communication. However, asymmetry in addressing can be represented by
making only the sender process to address the receiver process by its PID but the receiver process need
not to know the PID of the of the sender process. In case of asymmetric direct communication, the
calls send () and receive () will be defined as follows:
send(PID2, message)
receive(id, message)
Now, when the operating system delivers a message to process P2 upon the invocation of a receive ()
call by it, the parameter id is replaced with PID of the sender process.
Indirect communication
In indirect communication, messages are sent and received via a mailbox which is also known as a
port a repository (store) of Interprocess messages. A mail box, as the name implies, is just like a
postbox into which messages sent by the processes can be stored and removed by other processes. The
different characteristics of a mailbox are as follows:
Each mailbox has a unique ID and processes can communication with each other through a
number of mailboxes.
The process that creates the mailbox is the owner of mailbox and only this process can receive
messages from it. Other processes can only send messages to it. In other words, there can be
multiple senders but a single recipient for a mailbox.
A process that knows the ID of a mailbox can send messages to it.
Besides a user process, the operating system may also own a mail box. In this case, the operating
system may allow the processes to create or delete a mailbox, send and receive messages via mailbox.
The process that creates the mailbox becomes the owner of that mailbox and may receive messages
through this mailbox by passing ownership to them.
The system calls to send and receive a message to and from mailbox, x will be defined as follows:
send(x, message)
receive (x, message)
As stated earlier, a communication link must exist between processes before starting the
communication.
No buffering/ Zero capacity: The capacity of the buffer is zero, i.e. no messages may wait in
the queue. This implies that sender process has to wait until the message is received by the
receiver process.
Bounded buffer: The capacity of the buffer is fixed, n, i.e. at most n processes may wait in the
queue at a time. When there are less than n messages waiting in the queue and a new message
arrives, it is added in the queue and a new message arrives, it is added in the queue. The sender
process need not wait and it can resume its operation. However, if the queue is full, the sender
process is blocked until some space becomes available in the queue.
Unbounded buffer: The buffer has an unlimited capacity, i.e. an infinite number of messages
can be stored in the queue. In this case, the sender process never gets blocked.
Double buffering: Two buffers are shared between the sender and receiver process. In case
one buffer fills up, the second one is used. When the second buffer fills up, the first might
have been emptied. This way the buffers are used turn by turn, thus avoiding the blocking of
one process because of another.
Remote communication mechanisms
In an environment where processes are running on separate systems connected via a network, a
different mechanism is required to enable communication between these processes. Some mechanisms
that facilitate remote communication include:
Socket
Remote Procedure Call (RPC)
Remote Method Invocation (RMI)
Socket
A socket is defined as an end point of the communication path between two processes. Each of the
communicating processes creates a socket and these sockets are to be connected enabling
communication. The socket is identified by a combination of an IP address and a port number. The IP
address is used to identify the machine on the network and the port number is used to identify the
desired service on that machine. Sockets employ client server architecture. Whenever a client process
requests for a connection, it is assigned a port number by the host computer e.g. M. using this port
number and the IP address of host M, the client socket is created, e.g., if the client on host M having IP
address (125.61.15.7) wants to connect to Telnet server (listening to port number 23) having IP
address (112.56.71.8), it may be assigned a port number 1345. Thus, the client socket and server
socket used for communication will be (125.61.15.7:1345) and (112.56.71.8:23) respectively as shown
in the diagram below
Note: Each connection between the client and the server employs a unique pair of sockets, i.e. if
another client on host M wants to connect to Telnet server, it must be assigned a port number different
from 1345.
Remote Procedure Call (RPC)
Remote Procedure Call (RPC) is a communication mechanism that allows a process to call a procedure
on a remote system connected via a network. The calling process (client) can call the procedure on the
remote host (server) in the same way as it would call the local procedure. The syntax of RPC call is as
follows
Call <Procedure_id > (<List of parameters>);
The RPC system facilitates communication between the client and the server by providing a stub on
both client and server. For each remote procedure, the RPC system provides a separate stub on the
client side. When the client process wants to invoke a remote procedure, the RPC call is implemented
in the following steps:
1. The RPC system invokes the stub for the remote procedure on the client, passing to it the
parameters that are to be passed further to the remote procedure. The client process is
suspended from execution until the call is completed.
2. The client stub organizes parameters, which involves packaging the parameters into a machine
independent form so that they can be transmitted over the network. It now prepares a message
containing the identifier of the procedure to be executed and the organized parameters.
3. The client stub sends the message to the server. After the message has been sent, the client stub
blocks until it h-gets the reply to its message.
4. The corresponding stub on the server side receives the message and converts the parameters
into a machine specific form suitable for the server.
5. The server stub invokes the desired procedure, passing parameters to it. The server stub is
suspended from execution until completion of the call.
6. The procedure executes and the results are returned to the server stub.
7. The server stub converts the results into a machine independent form and prepares a message.
8. The server stub sends the message containing the results to the client stub.
9. The client stub converts the results into machine specific form suitable for the client.
10. The client stub forwards the results to the client process. With this, the execution of RPC is
completed, and now, the client process can continue its execution.
The figure below depicts all the steps involved in the execution of RPC
Equivalent of primitives
Many new inter process communication mechanisms can be built from the four different inter process
communication primitives, semaphores, monitors, messages and event counters. The following are the
essential equivalence of semaphores, monitors, and messages.
Using semaphores to implement monitors and messages
Using monitors to implement semaphores and messages
Using messages to implement semaphores and monitors
References
William Stallings (2009) Operating systems internals and design principles. Dorling
Kindersley publishing, Inc.
H.M Deitel, P.J Deitel, D.R Choffnes (2007) Operating systems. Pearson Education, Inc. and
Dorling Kindersley publishing, Inc.
D.M Dhamdhere (2003) Operating systems, a concept based approach. Tata McGraw Hill
Publishing Company Limited.
Milan Milenkovic (2002) Operating systems, concepts and design. Tata McGraw Hill
Publishing Company Limited.
A.S Tanenbaum, A.S Woodhull (2002) Operating systems design and implementation. Pearson
Education, Inc.
Rohit Khurana (2014) Operating Systems, Vika publishing house PVT Limited.
Iresh A.Dhotre (2009) Operating Systems, Technical Publish Pune.