Inter Process Communication
Inter Process Communication
Pipes
Pipe is widely used for communication between two related processes. This is a half-duplex
method, so the first process communicates with the second process. However, in order to
achieve a full-duplex, another pipe is needed.
Message Passing:
It is a mechanism for a process to communicate and synchronize. Using message passing,
the process communicates with each other without resorting to shared variables.
Message Queues:
A message queue is a linked list of messages stored within the kernel. It is identified by a
message queue identifier. This method offers communication between single or multiple
processes with full-duplex capacity.
Direct Communication:
In this type of inter-process communication process, should name each other explicitly. In
this method, a link is established between one pair of communicating processes, and
between each pair, only one link exists.
Indirect Communication:
Indirect communication establishes like only when processes share a common mailbox each
pair of processes sharing several communication links. A link can communicate with many
processes. The link may be bi-directional or unidirectional.
Shared Memory:
Shared memory is a memory shared between two or more processes that are established
using shared memory between all the processes. This type of memory requires to protected
from each other by synchronizing access across all the processes.
FIFO:
Communication between two unrelated processes. It is a full-duplex method, which means
that the first process can communicate with the second process, and the opposite can also
happen.
Why IPC?
Here, are the reasons for using the interprocess communication protocol for information
sharing:
A shared memory segment is described by a control structure with a unique ID that points
to an area of physical memory. The identifier of the segment is called the shmid. The
structure definition for the shared memory segment control structures and prototypes can
be found in <sys/shm.h>.
Examples
We will write two programs for IPC using shared memory as an example. Program 1 will
create the shared segment, attach it, and then write some content in it. Then Program 2
will attach itself to the shared segment and read the value written by Program 1.
Program 1: This program creates a shared memory segment, attaches itself to it, and
then writes some content into the shared memory segment.
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/shm.h>
#include<string.h>
int main()
{
int i;
void *shared_memory;
char buff[100];
int shmid;
shmid=shmget((key_t)2345, 1024, 0666|IPC_CREAT);
//creates shared memory segment with key 2345, having size 1024 bytes.
IPC_CREAT is used to create the shared segment if it does not exist. 0666 are
the permissions on the shared segment
printf("Key of shared memory is %d\n",shmid);
shared_memory=shmat(shmid,NULL,0);
//process attached to shared memory segment
printf("Process attached at %p\n",shared_memory);
//this prints the address where the segment is attached with this process
printf("Enter some data to write to shared memory\n");
read(0,buff,100); //get some input from user
strcpy(shared_memory,buff); //data written to shared memory
printf("You wrote : %s\n",(char *)shared_memory);
}
Output
In the above program, the shmget() function creates a segment with key 2345,
size 1024 bytes, and reads and writes permissions for all users. It returns the
identifier of the segment, which gets stored in shmid. This identifier is used in
shmat() to attach the shared segment to the process's address space.
NULL in shmat() means that the OS will itself attach the shared segment at a
suitable address of this process. Then some data is read from the user using the
read() system call, and it is finally written to the shared segment using the
strcpy() function.
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/shm.h>
#include<string.h>
int main()
{
int i;
void *shared_memory;
char buff[100];
int shmid;
shmid=shmget((key_t)2345, 1024, 0666);
printf("Key of shared memory is %d\n",shmid);
shared_memory=shmat(shmid,NULL,0); //process attached to shared memory
segment
printf("Process attached at %p\n",shared_memory);
printf("Data read from shared memory is : %s\n",(char *)shared_memory);
}
Output
In this program, shmget() here generates the identifier of the same segment as
created in Program 1. Remember to give the same key value. The only change is,
do not write IPC_CREAT as the shared memory segment is already created.
Next, shmat() attaches the shared segment to the current process.
After that, the data is printed from the shared segment. In the output, you will
see the same data that you have written while executing Program 1.
Example program 1 − Program to write and read two messages using pipe.
Algorithm
Step 1 − Create a pipe.
Step 3 − Retrieve the message from the pipe and write it to the standard output.
Step 5 − Retrieve the message from the pipe and write it to the standard output.
Note − Retrieving messages can also be done after sending all messages.
#include<stdio.h>
#include<unistd.h>
int main() {
int pipefds[2];
int returnstatus;
char writemessages[2][20]={"Hi", "Hello"};
char readmessage[20];
returnstatus = pipe(pipefds);
if (returnstatus == -1) {
printf("Unable to create pipe\n");
return 1;
}
Example program 2 − Program to write and read two messages through the pipe
using the parent and the child processes.
Algorithm
Step 1 − Create a pipe.
Step 4 − Child process retrieves the message from the pipe and writes it to the
standard output.
#include<stdio.h>
#include<unistd.h>
int main() {
int pipefds[2];
int returnstatus;
int pid;
char writemessages[2][20]={"Hi", "Hello"};
char readmessage[20];
returnstatus = pipe(pipefds);
if (returnstatus == -1) {
printf("Unable to create pipe\n");
return 1;
}
pid = fork();
// Child process
if (pid == 0) {
read(pipefds[0], readmessage, sizeof(readmessage));
printf("Child Process - Reading from pipe – Message 1 is %s\n",
readmessage);
read(pipefds[0], readmessage, sizeof(readmessage));
printf("Child Process - Reading from pipe – Message 2 is %s\n",
readmessage);
} else { //Parent process
printf("Parent Process - Writing to pipe - Message 1 is %s\n",
writemessages[0]);
write(pipefds[1], writemessages[0], sizeof(writemessages[0]));
printf("Parent Process - Writing to pipe - Message 2 is %s\n",
writemessages[1]);
write(pipefds[1], writemessages[1], sizeof(writemessages[1]));
}
return 0;
Execution Steps
Compilation
gcc pipewithprocesses.c –o pipewithprocesses
Execution
Parent Process - Writing to pipe - Message 1 is Hi
Parent Process - Writing to pipe - Message 2 is Hello
Child Process - Reading from pipe – Message 1 is Hi
Child Process - Reading from pipe – Message 2 is Hello