Ipc OS
Ipc OS
Why is it needed?
Processes may need to share data
More than one process reading/writing the same data
(a shared file, a database record,)
Output of one process being used by another
Needs mechanisms to pass data between processes
Interprocess Communication
(IPC)
Mechanism for processes P and Q to
communicate and to synchronize their actions
Establish a communication link
Implementation Questions
How are links established?
Can a link be associated with more than two
processes?
How many links can there be between every pair
of communicating processes?
What is the capacity of a link?
Is the size of a message that the link can
accommodate fixed or variable?
Is a link unidirectional or bi-directional?
Bounded-Buffer Shared-Memory
Solution
Shared data
#define BUFFER_SIZE 10
typedef struct {
...
} item;
item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
Bounded-Buffer:
Producer Process
item nextProduced;
while (1) {
while (((in + 1) % BUFFER_SIZE) == out)
; /* do nothing */
buffer[in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
}
Bounded-Buffer:
Consumer Process
item nextConsumed;
while (1) {
while (in == out)
; /* do nothing */
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
}
Producer process
Shared data
#define B_SIZE 10
typedef struct {
...
} item;
item buffer[B_SIZE];
int in = 0;
int out = 0;
int counter = 0;
item nextProduced;
while (1) {
while (counter == BUFFER_SIZE)
; /* do nothing */
buffer[in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
Consumer process
item nextConsumed;
while (1) {
while (counter == 0)
; /* do nothing */
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
}
An Illustration
Assume counter is initially 5. One interleaving of
statements is:
producer: register1 = counter (register1 = 5)
producer: register1 = register1 + 1 (register1 = 6)
consumer: register2 = counter (register2 = 5)
consumer: register2 = register2 1 (register2 = 4)
producer: counter = register1 (counter = 6)
consumer: counter = register2 (counter = 4)
Race Condition
A scenario in which the final output is dependent
on the relative speed of the processes
Example: The final value of the shared data counter
depends upon which process finishes last
Atomic Operation
An operation that is either executed fully without
interruption, or not executed at all
The operation can be a group of instructions
Ex. the instructions for counter++ and counter-Note that the producer-consumer problems solution
works if counter++ and counter-- are made atomic
In practice, the process may be interrupted in the middle
of an atomic operation, but the atomicity should ensure
that no process uses the effect of the partially executed
operation until it is completed
entry section
critical section
exit section
remainder section /*remaining code */
Solutions vary depending on how these sections are
written
Petersens Solution
Only 2 processes, P0 and P1
Processes share some common variables to
synchronize their actions
int turn = 0
turn = i Pi s turn to enter its critical section
boolean flag[2]
initially flag [0] = flag [1] = false
flag [i] = true Pi ready to enter its critical section
Process Pi
do {
flag [i]:= true;
turn = j;
while (flag [j] and turn = j) ;
critical section
flag [i] = false;
remainder section
} while (1);
Meets all three requirements; solves the criticalsection problem for two processes
Can be extended to n processes by pairwise mutual
exclusion too costly
Bakery Algorithm
Notation < lexicographical order (ticket #,
process id #)
(a,b) < c,d) if a < c or if a = c and b < d
max (a0,, an-1) is a number, k, such that k ai for i 0,
, n 1
Shared data
boolean choosing[n];
int number[n];
Data structures are initialized to false and 0
respectively
Bakery Algorithm
do {
choosing[i] = true;
number[i] =
max(number[0], number[1], , number [n 1]) +1;
choosing[i] = false;
for (j = 0; j < n; j++) {
while (choosing[j]) ;
while ((number[j] != 0) &&
(number[j,j] < number[i,i])) ;
}
critical section
number[i] = 0;
remainder section
} while (1);
Semaphore
Widely used synchronization tool
Does not require busy-waiting
CPU is not held unnecessarily while the process is
waiting
A Semaphore S is
A data structure with an integer variable S.value and a
queue S.q of processes
The data structure can only be accessed by two
atomic operations, wait(S) and signal(S) (also called
P(S) and V(S))
Pj
M
wait(flag)
B
Pitfalls
Use carefully to avoid
Deadlock two or more processes are waiting
indefinitely for an event that can be caused by only
one of the waiting processes
Starvation indefinite blocking. A process may
never be removed from the semaphore queue in
which it is suspended
Example of Deadlock
Let S and Q be two semaphores initialized to 1
P0
wait(S);
wait(Q);
M
signal(S);
signal(Q)
P1
wait(Q);
wait(S);
M
signal(Q);
signal(S);
Internal Implementations of
Semaphores
How do we make wait and signal atomic?
Should we use another semaphore? Then who makes that
atomic?
Classical Problems of
Synchronization
Bounded-Buffer Producer-Consumer Problem
Readers and Writers Problem
Dining-Philosophers Problem
Bounded-Buffer Problem
Shared data
semaphore full, empty, mutex;
Initially:
full = 0, empty = n, mutex = 1
Bounded-Buffer Problem:
Producer Process
do {
wait(empty);
wait(mutex);
signal(mutex);
signal(full);
} while (1);
Bounded-Buffer Problem:
Consumer Process
do {
wait(full)
wait(mutex);
signal(mutex);
signal(empty);
} while (1);
Readers-Writers Problem
A common shared data
Reader process only reads data
Writer process only writes data
Synchronization requirements
Writers should have exclusive access to the data
No other reader or writer can access the data at that
time
Multiple readers should be allowed to access the data
if there is no writer accessing the data
Writer
wait(wrt);
perform write
signal(wrt);
Reader
wait(mutex);
readcount++;
if (readcount == 1)
wait(rt);
signal(mutex);
perform read
wait(mutex);
readcount--;
if (readcount == 0)
signal(wrt);
signal(mutex):
Dining-Philosophers Problem
Shared data
semaphore chopstick[5];
Initially all values are 1
Dining-Philosophers Problem
Philosopher i:
do {
wait(chopstick[i])
wait(chopstick[(i+1) % 5])
eat
signal(chopstick[i]);
signal(chopstick[(i+1) % 5]);
think
} while (1);
Other Synchronization
Constructs
Programming constructs
Specify critical sections or shared data to be protected
by mutual exclusion in program using special
keywords
Compiler can then insert appropriate code to enforce
the conditions (for ex., put wait/signal calls in
appropriate places in code)
Examples
Critical regions, Monitors, Barriers,