The Pipe Model


One way to visualize a pipe is a one-way connector between two entities. For example, consider the following GNU/Linux command:

 ls -1  wc -l 

This command creates two processes, one for the ls -1 and another for wc -l . It then connects the two together by setting the standard-input of the second process to the standard-output of the first process (see Figure 11.1). This has the effect of counting the number of files in the current subdirectory.

click to expand
Figure 11.1:    Simple pipe example.

Our command, as illustrated in Figure 11.1, sets up a pipeline between two GNU/Linux commands. The ls command is performed, which generates output that is used as the input to the second command, wc (word count). This is a half-duplex pipe as communication occurs in one direction. The linkage between the two commands is facilitated by the GNU/Linux kernel, which takes care of connecting the two together. We can achieve this as well in applications, which we ll demonstrate shortly.

Pipes and Named Pipes

A pipe, or half-duplex pipe, provides the means for a process to communicate with one of its ancestral subprocesses (of the anonymous variety). This is because there s no way in the operating system to locate the pipe (it s anonymous). It s most common use is to create a pipe at a parent process and then pass the pipe to the child so that they can communicate. Note that if full-duplex communication was required, the Sockets API should be considered instead.

Another type of pipe is called a named pipe . A named pipe works like a regular pipe but exists in the filesystem so that any process can find it. This means that processes not of the same ancestry are able to communicate with one another.

We ll look at both pipes and named pipes in the following sections. We ll first take a quick tour of pipes and then follow up with a more detailed look at the pipe API and GNU/Linux system-level commands that support pipes programming.

Whirlwind Tour

Let s begin with a simple example of the pipe programming model. In this simple example, we ll create a pipe within a process, write a message to it, read the message back from the pipe, and then emit it (see Listing 11.1).

Listing 11.1: Simple Pipe Example (on the CD-ROM at ./source/ch11/pipe1.c )
start example
  1:  #include <unistd.h>  2:  #include <stdio.h>  3:  #include <string.h>  4:   5:  #define MAX_LINE        80  6:  #define PIPE_STDIN      0  7:  #define PIPE_STDOUT     1  8:   9:  int main()  10:  {  11:  const char *string={"A sample message."};  12:  int ret, myPipe[2];  13:  char buffer[MAX_LINE+1];  14:   15:  /* Create the pipe */  16:  ret =  pipe  ( myPipe );  17:   18:  if (ret == 0) {  19:   20:  /* Write the message into the pipe */  21:   write  ( myPipe[PIPE_STDOUT], string, strlen(string) );  22:   23:  /* Read the message from the pipe */  24:  ret =  read  ( myPipe[PIPE_STDIN], buffer, MAX_LINE );  25:   26:  /* Null terminate the string */  27:  buffer[ ret ] = 0;  28:   29:  printf("%s\n", buffer);  30:   31:  }  32:   33:  return 0;  34:  } 
end example
 

In Listing 11.1, we create our pipe using the pipe call at line 16. We pass in a two-element int array that represents our pipe. The pipe is defined as a pair of separate file descriptors, an input and an output. We can write to one end of the pipe and read from the other. The pipe API function returns zero on success. Upon return, the myPipe array will contain two new file descriptors representing the input to the pipe ( myPipe[1] ) and the output from the pipe ( myPipe[0 ]).

At line 21, we write our message to the pipe using the write function. We specify the stdout descriptor (from the perspective of the application, not the pipe). The pipe now contains our message and can be read at line 24 using the read function. Here again, from the perspective of the application, we use the stdin descriptor to read from the pipe. The read function stores what is read from the pipe in the buffer variable (argument three of the read function). We terminate it (add a NULL to the end) so that we can properly emit it at line 29 using printf . The pipe in this example is illustrated in Figure 11.2.

click to expand
Figure 11.2:    Half-duplex pipe example from Listing 11.1.

While this example was entertaining, communicating with ourselves could be performed using any number of mechanisms. In the detailed review, we ll look at more complicated examples that provide communication between processes (both related and unrelated).




GNU/Linux Application Programming
GNU/Linux Application Programming (Programming Series)
ISBN: 1584505680
EAN: 2147483647
Year: 2006
Pages: 203
Authors: M. Tim Jones

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net