Un-named Pipes

  • A pipe is a communication between two processes, such that output of one process becomes the input of another process.
  • There are two types of pipes: named pipes and unnamed pipes(anonymous pipes).
  • Unlike other forms of inter-process communication(IPC), an un-named pipe is a one way communication.
  • For two-way communication between processes, two pipes can be set up, one for each direction.
  • Communication is achieved by one process writing into the pipe and other process reading from the pipe.
  • One process cannot read from the buffer until another has written into to it.
  • A limitation of un-named for inter-process communication is that that the processes using pipes must be related like having a common parent or between parent process and child process obtained via fork() API.
  • Anonymous pipes are always local; they cannot be used for communication over a network.
  • The UNIX command-line interpreter(e.g., csh) provides the pipe facility.
    • ps -aux | grep 1234
    • This command gives the process utility output to another utility name grep.
Pipe implementation

The shell arranges the standard input and output of the two commands, so that

  • The standard input to cmd1 comes from the terminal keyboard.
  • The standard output form cmd1 is fed to cmd2 as its standard input.
  • The standard output from cmd2 is connected to the terminal screen

Pipe System call

  • The pipe() system call would create a pipe for one way communication.
  • This pipe exists in an main memory and is treated as virtual file.
  • If a process tries to read before something is written, the process is suspended until something is written.
  • The pipe system call finds the first two available positions in the processes open file table and allocates them for read and write ends of the pipe.
int pipe (fd[2]);
  • It creates two file descriptors, that is fd[0]] for reading and fd[1] for witting.
  • It returns 0 on success and -1 on failure.

Sample Program-1:
This is a simple program for showing the use of pipe within a single process.

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
   int pipe_fd[2];
   int data_processed;
   char buffer[20];
   char *msg = "Hello how are you";
   memset (buffer, '\0', sizeof(buffer));
   
   int result = pipe (pipe_fd);
   if (result == -1)
   {
     printf("\n Pipe creation failed %s\n", strerror(errno));
     exit (EXIT_FAILURE);
   }
   printf("\n Pipe created successfully..\n");
   printf("\n Pipe read descriptor: %d\n", pipe_fd[0]);
   printf("\n Pipe write descriptor: %d\n", pipe_fd[1]);
   
   data_processed = write (pipe_fd[1], msg, strlen(msg));
   printf("\n Data send is: %s, length is: %d\n", msg, data_processed);
   
   data_processed = read (pipe_fd[0], buffer, sizeof(buffer));
   printf("\n Data read is: %s, length is: %d\n", buffer, data_processed);
   
   return 0;
}

 Output:
 gcc pipe.c 
 ./a.out
 Pipe created successfully..
 Pipe read descriptor: 3
 Pipe write descriptor: 4

 Data send is: Hello how are you, length is: 17
 Data read is: Hello how are you, length is: 17

...Program finished with exit code 0
Press ENTER to exit console.

The above program could have even done with file, the real advantage of pipe comes when data is passed between process.

Sample Program-2:
This program is for sending data between process, parent and child process created using fork() and wait(). Please refer fork() and wait() for a clear understanding of the below program.

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
   int pipe_fd[2];
   int data_processed;
   char buffer[20];
   char *msg = "Hello how are you";
   memset(buffer, '\0', sizeof(buffer));
   
   int result = pipe (pipe_fd);
   if (result == -1)
   {
     printf("\n Pipe creation failed %s\n", strerror(errno));
     exit (EXIT_FAILURE);
   }
   printf("\n Pipe created successfully\n");
   
   result = fork();
   if (result == -1)
   {
     printf("\n Fork failed %s\n", strerror(errno));
     exit (EXIT_FAILURE);
   }
   
   if (result !=0) /* Parent process */
   {
      int stat_val;
      data_processed = write (pipe_fd[1], msg, strlen(msg));
      printf("\n Data send is: %s of length: %d\n", msg, data_processed);
       
      /* wait() is called so that the child terminates before the parent and resources of child are freed, else it may create zombie process */
      printf("\n Waiting for child to finish\n");
      int child_pid = wait (&stat_val);
      if (child_pid == -1)
      {
           printf("\n There is no child process \n");
           exit(EXIT_FAILURE);
      }
      if (WIFEXITED(stat_val))
         printf("\n Child terminated Normally\n");
      else
         printf("\n Child terminated Abnormally");
        
   }
   
   if (result ==0) /* Child process */
   {
       data_processed = read (pipe_fd[0], buffer, sizeof(buffer));
       printf("\n Data read is: %s of length: %d\n", buffer, data_processed);
       
   }
   return 0;
}
 Output:
 gcc pipe.c 
 ./a.out

 Pipe created successfully

 Data send is: Hello how are you of length: 17
 Waiting for child to finish

 Data read is: Hello how are you of length: 17
 Child terminated Normally

Sample Program-3:
This is for use of pipe() for data transfer among parent and child process but child process is a different program from its parent. The child process execute a new program by the use execl() function call. Please read fork(), wait(), execl() functions call for the better understanding of the below program

Parent process(pipe_execl.c)

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

int main()
{
  int pipe_fd[2];
  int data_processed;
  char *msg = "Hello how are u";
  char buffer[10];
  memset (buffer, '\0', sizeof(buffer));

  int result = pipe (pipe_fd);
  if (result == -1)
  {
          printf ("\n Pipe creation failed %s\n", strerror(errno));
          exit (EXIT_FAILURE);
  }
  printf ("\n Pipe created successfully\n");
  result = fork();
  if (result == -1)
  {
          printf ("\n Fork failed %s\n", strerror(errno));
          exit (EXIT_FAILURE);
  }

  if (result !=0) /* Parent process */
  {
    int stat_val;
    data_processed = write (pipe_fd[1], msg, strlen(msg));
    printf ("\n Data send is: %s of length: %d\n", msg, data_processed);

    printf ("\n Waiting for child to finish\n");
    int child_pid = wait (&stat_val);
    if (child_pid == -1)
    {
     printf ("\n There is no child process \n");
     exit (EXIT_FAILURE);
    }
    if (WIFEXITED(stat_val))
       printf("\n Child terminated Normally\n");
     else
        printf("\n Child terminated Abnormally");
 
   }
   else /* Child process */
   {
     sprintf (buffer, "%d", pipe_fd[0]);
     result = execl ("pipe_new_image", "pipe_execl", buffer, NULL);
     if (result == -1)
     {
         printf ("\n execl failed %s\n", strerror(errno));
         exit (EXIT_FAILURE);
     }
   }
  return 0;
 }

                                                                     

Child process(pipe_new_image.c)

  #include <stdio.h>
  #include <string.h>
 
  int main (int argc, char *argv[])
  {
    printf ("\n Executing new image\n");
    int data_processed, fd;
    char buffer[20];
    memset (buffer, '\0', sizeof(buffer));
    sscanf (argv[1], "%d", &fd);
 
    data_processed = read (fd, buffer, sizeof(buffer));
    printf ("\n Data read is: %s of length: %d\n", buffer, data_processed);
 
    return 0;
 }

Output:

[aprakash@wtl-lview-6 thread]$ gcc pipe_new_image.c -o pipe_new_image
[aprakash@wtl-lview-6 thread]$ gcc pipe_execl.c 
[aprakash@wtl-lview-6 thread]$ ./a.out 

 Pipe created successfully

 Data send is: Hello how are u of length: 15

 Waiting for child to finish

 Executing new image

 Data read is: Hello how are u of length: 15

 Child terminated Normally
Formal Powerpoint presentation
Pipe: Parent and Child Process

Related Topics:



Categories: Operating system (OS)

3 replies

  1. Excellent composition at a glance

    Like

Trackbacks

  1. Index of Operating System - Tech Access
  2. Inter-Process Communication(IPC) - Tech Access

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: