Monday, April 25, 2016

IPC: Process communication using PIPE

Pipes are basically used for communicating information between two processes.



There are two types of pipes:
  1. ordinary pipe
  2. Named pipe

Ordinary Pipe:

  • simple pipes are unidirectional in nature (one-way comm)
  • two-way communication can be achieved by creating 2 pipes
  • pipe cannot be accessed from the outside the process that creates it
  • Hence it is used mostly for parent and child process communication

creation and use:


  • pipe() function is used to create a pipe. This actually creates special file
  • read(), write(), close() system calls can be used to access this file
  • int file_descriptor[2] array is used as file_descriptor to access file.
    • file_descriptor[0] = read from file
    • file_descriptor[1] = write to file
  • one of the file descriptor(read/write) should be closed in the respective process to make it unidirectional. This is done to avoid Deadlock condition and exploit parallelism

Named Pipes:

  • named pipes are like FIFOs
  • created using mkfifo() system calls and opereated using open, read, write and close(0 system calls
  • they appear as files in file system once created
  • they remain as it is until they are deleted explicitly
  • multiple process on same machine can use named pipe
  • For communication over network, socket wrapper need to be used
Named pipe Example:
$mkfifo demo_fifo
$exec 3<> demo_fifo
$ls -l >&3
$cat demo_fifo

mkfifo - create named pipe
exec - to a assigned 3 as file descriptor for named pipe
$ls -l >&3  add output of ls -l to named pipe
cat - read the data from named pipe

Following is example of Ordinary pipe:
---------------------------------------------------------------------------------
linux_pipe.c
---------------------------------------------------------------------------------

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 50
#define READ_END 0
#define WRITE_END 1

int main(int argc, char *argv[]){
char write_msg[BUFFER_SIZE] = "message over pipe";
char read_msg[BUFFER_SIZE];
int file_descriptor[2];

pid_t pid;

// create pipe
if (pipe(file_descriptor) == -1){
fprintf(stderr, "ERROR: Pipe creation failed");
return 1;
}

pid = fork(); // fork process
if (pid < 0){ // process forking failure
fprintf(stderr, "ERROR: Process forking failure");
}
else if (pid == 0){ //this is child process
printf("Inside child process\n");
close(file_descriptor[WRITE_END]); //close the write end of the pipe
read(file_descriptor[READ_END], read_msg, BUFFER_SIZE); //read message from pipe. wait until message is received
printf("Read data = %s", read_msg);
close(file_descriptor[READ_END]); //close read end of the pipe
}
else { //this is parent process
sleep(5); //Too verify child waits at read() for 5sec until it receives message
close(file_descriptor[READ_END]); //close read end of the pipe
write(file_descriptor[WRITE_END], write_msg, strlen(write_msg) + 1); //writing message to pipe
printf("Task of writing message to pipe completed\n");
close(file_descriptor[WRITE_END]); //close write end of the pipe
}

return 0;
}


---------------------------------------------------------------------------------
output
---------------------------------------------------------------------------------

Inside child process

Task of writing message to pipe completed
Read data = message over pipe

No comments:

Post a Comment

PROFILE

My photo
India
Design Engineer ( IFM Engineering Private Limited )

Followers