Saturday 3 December 2016

Pipes

      A pipe is a communication device that permits unidirectional communication.
      Data is written to the “write end” of the pipe and is read back from the “read end.”
      Pipes are serial devices; the data is always read from the pipe in the same order it was written.
      Typically, a pipe is used to communicate between two threads in a single process or between parent and child processes.
      In a shell, the symbol “| “creates a pipe.
      For example, this shell command causes the shell to produce two child processes, one for ls and one for less:
      $ ls | less
     The shell also creates a pipe connecting the standard output of the “ls” subprocess with the standard input of the “less” process.
     The filenames listed by “ls” are sent to “less” in exactly the same order as if they were sent directly to the terminal.
      A pipe’s data capacity is limited. If the writer process writes faster than the reader process consumes the data, and if the pipe cannot store more data, the writer process blocks until more capacity becomes available.
      If the reader tries to read but no data is available, it blocks until data becomes available. Thus, the pipe automatically synchronizes the two processes
      To create a pipe, invoke the “pipe” command.
      Synonpsis
     #include <unistd.h>
     int pipe(int pipefd[2]);
     Supply an integer array of size 2. The array is used to return two file descriptors referring to ends of the pipe
     The call to pipe stores the reading file descriptor in array position 0 and the writing file descriptor in position 1.
     For example, consider this code:
int pipe_fds[2];
int read_fd;
int write_fd;
pipe (pipe_fds);
read_fd = pipe_fds[0];
write_fd = pipe_fds[1];

Communication between Parent and Child Processes
      A call to pipe creates file descriptors, which are valid only within that process and its children.
      A process’s file descriptors cannot be passed to unrelated processes; however, when the process calls fork, file descriptors are copied to the new child process.
      Thus, pipes can connect only related  processes

Example: The parent writes the string contained in the program's command-line argument to the pipe, and the child reads this string a byte at a time from the pipe and echoes it on standard output.
#include <sys/wait.h>
#include <stdio.h>
 #include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[]) {      
int pipefd[2];
          pid_t cpid;
          char buf;
          if (argc != 2) {
                    exit(EXIT_FAILURE);
          }
          if (pipe(pipefd) == -1) {
                   exit(EXIT_FAILURE);
          }
          cpid = fork();
          if (cpid == -1) {   
                   exit(EXIT_FAILURE);
          }
if (cpid == 0) {
/* Child reads from pipe */
          close(pipefd[1]); // Close unused write end
          while (read(pipefd[0], &buf, 1) > 0) write(STDOUT_FILENO, &buf, 1);
          close(pipefd[0]); exit(EXIT_SUCCESS);
}
else { /* Parent writes argv[1] to pipe */
          close(pipefd[0]); /* Close unused read end */
          write(pipefd[1], argv[1],  strlen(argv[1]));
          close(pipefd[1]);

          wait(NULL); /* Wait for child */ exit(EXIT_SUCCESS); } }

No comments:

Post a Comment