Linux Programming pipe () function detailed _linux

Source: Internet
Author: User

A pipeline is a mechanism that connects standard input and standard output between two processes to provide a way to communicate between multiple processes, and when a process creates a pipeline, it needs to provide two file descriptors each time to manipulate the pipeline. One writes to the pipe and the other reads the pipe. The reading and writing of the pipe is consistent with the general IO system function, writes the data using the Write () function, and reads the data using read ().

#include <unistd.h>

int pipe (int filedes[2]);

Return value: Success, return 0, otherwise return-1. The parameter array contains a descriptor for the two files used by pipe. FD[0]: Read pipe, fd[1]: Write pipe.

Pipe () must be invoked in fork (), otherwise the child process will not inherit the file descriptor. Two processes do not share ancestor processes and cannot use pipe. However, you can use named pipes.


When the pipe is written, if the written data is less than 128K and is not atomic, if it is greater than 128K bytes, the data of the buffer will be continuously written to the pipeline until all the data has been written, and if no process has read the data, it will block as follows:

In the previous example, the child process writes 128K data at a time, and when the parent process reads all the data, the write () function of the child process ends blocking and

Returns the write information.

Named pipe FIFO

The biggest disadvantage of a pipeline is that it has no name and can only be used between processes that have a common ancestor process. FIFO represents advanced first out, single it is a one-way data flow, that is, Half-duplex, and

The difference between pipelines is that each FIFO has a path associated with it, allowing unrelated process access.

#include <sys/types.h>

    #include <sys/stat.h>

   int mkfifo (const char *pathname, mode_t mode);

Here pathname is the pathname, mode is the permission to create the file defined within Sys/stat.h.

Examples of FIFO between relational processes

* * * The use of a simple example of a FIFO using a relational process * * * #include ". /all.h "#define Fifo_path"/tmp/hover_fifo "void Do_sig (int signo) {if (Signo = sigchld) while (Waitpid ( -1, NU
LL, Wnohang) > 0);
  int main (void) {int ret;
  int FDR, FDW;

  pid_t pid;
  Char words[10] = "123456789";  
  
  Char buf[10] = {' I '};

  Create it, if it exists it is not an error,//If you want to modify its properties, you need to open to get the FD first, then use Fcntl to get the properties, and then set the properties.
  if ((ret = Mkfifo (Fifo_path, file_mode)) = = 1) && (errno!= eexist)) perr_exit ("Mkfifo ()");

  fprintf (stderr, "FIFO:%s created successfully!\n", Fifo_path);

  Signal (SIGCHLD, do_sig);
  PID = fork ();
    if (PID = = 0) {//child if (FDR = open (Fifo_path, o_wronly)) < 0)//open FIFO to write Perr_exit ("open ()");

    Sleep (2);
    Write Data if (write (FDR, words, sizeof (words))!= sizeof (words)) perr_exit ("write");
    fprintf (stderr, "Child write:%s\n", words);
  Close (FDW); else if (PID > 0) {//parent if (FDR = open (Fifo_path, O_rdonly)) < 0)//open FIFO to read Perr_exit ("open ()");
    fprintf (stderr, "I father read, waiting for child ... \ n");

    if (read (FDR, BUF, 9)!= 9)/Read Data perr_exit ("read");
    fprintf (stderr, "Father get buf:%s\n", buf);
  Close (FDR);

  The FIFO pipeline has not been deleted and must be manually called to the function unlink or remove.  
return 0;

 }

As you can see from the example, using FIFO requires attention:

The *fifo pipe is first called Mkfifo and then used with open to get FD.

* When opening FIFO, be aware that it is half-duplex and generally cannot be opened with O_RDWR and can only be opened with read-only or write-only.

FIFO can be used between unrelated processes, and its true use is between the server and the client. Because it is Half-duplex, if you want to communicate between the client and the server,

Each direction must establish two pipes, one for reading and one for writing.

Here is a server, a FIFO example for multiple clients:

Server-side Example:

/* FIFO Server */#include "all.h" int main (void) {int FDW, FDW2;
  int FDR;
  Char Clt_path[path_len] = {' I '};
  Char Buf[max_line] = {' I '};
  Char *p;
  
  int n;  
  if (Mkfifo (fifo_svr, file_mode) = = 1 && errno!= eexist) perr_exit ("Mkfifo ()");
  if ((FDR = open (Fifo_svr, o_rdonly)) < 0) Perr_exit ("Open ()"); 

   * * According to the creation of FIFO rules, if from an empty pipe or FIFO read, * and before reading the pipe or FIFO has opened to write operations, then read operation will be blocked until the pipe or FIFO does not open to read, or in the pipeline or FIFO data.
   * Here, our FIFO was originally opened for reading, but in order to, read does not return 0, * Let each client end read all blocked on the FIFO, we open again to read.
  
  * See Unpv2 Charper 4.7/if (FDW2 = open (Fifo_svr, o_wronly)) < 0) fprintf (stderr, "open ()"); 

   while (1) {/* Read client FIFO path from FIFO_SVR//* Here because the FIFO_SVR has open to write operation, so when the pipeline has no data, * Read will block, not return 0. */if (read (FDR, Clt_path, Path_len) < 0) {fprintf (stderr, "read FIFO client path error:%s\n", Strerro  
      R (errno));
    Break
     } if (P = strstr (Clt_path, "\ r \ n")) = = NULL) { fprintf (stderr, "Clt_path Error:%s\n", Clt_path);
    Break
    } *p = ' I ';
    DBG ("Clt_path", Clt_path);  
      if (Access (Clt_path, W_OK) = = 1) {//client FIFO OK, but no permission perror ("Access ()");
    Continue  
      }/* Open client FIFO for write */if (FDW = open (Clt_path, o_wronly)) < 0) {perror ("open ()");
    Continue  } if ((n = Read (FDR, BUF, Words_len)) > 0) {/* Read server WORDS is OK */printf ("Server Read WORDS:%s\n",
      BUF);
      Buf[n] = ' the ';  
    Write (FDW, buf, strlen (BUF));  
  } close (FDW);
  Unlink (FIFO_SVR);
Exit (0);

 }

Example of a client:  

* * * FIFO Client * * */#include "all.h" int main (void) {int FDR, FDW;  
  pid_t pid;
  Char Clt_path[path_len] = {' I '};
  Char Buf[max_line] = {' I '};
  
  Char Buf_path[max_line] = {' I '};    
  snprintf (Clt_path, Path_len, Fifo_clt_fmt, (Long) getpid ());
  DBG ("clt_path1 =", Clt_path);

  snprintf (Buf_path, Path_len, "%s\r\n", Clt_path);

  if (Mkfifo (Clt_path, file_mode) = = 1 && errno!= eexist) perr_exit ("Mkfifo ()"); /* Client Open Clt_path for read * Open server for Write */if (FDW = open (Fifo_svr, o_wronly)) < 0 PE
  
  Rr_exit ("open ()");
  /* Write my FIFO path to server */if (write (FDW, Buf_path, Path_len)!= Path_len) Perr_exit ("Write ()");

  if (Write (FDW, WORDS, Words_len) < 0)/* Write WORDS to FIFO server/perr_exit ("error");
  if ((FDR = open (Clt_path, o_rdonly)) < 0) Perr_exit ("Open ()");
    if (read (FDR, buf, Words_len) > 0) {/* read reply from FIFO server */buf[words_len] = '; prINTF ("Server said:%s\n", buf);
  Close (FDR);
  
  Unlink (Clt_path);
Exit (0);

 }

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.