About Linux IPC (vi): Pipe and FIFO

Source: Internet
Author: User

"Copyright Notice: respect for the original, reproduced please retain the source: blog.csdn.net/shallnet or .../gentleliu, the article is for learning communication only, do not use for commercial purposes"
The earliest IPC form on UNIX systems is pipeline, and pipeline creation uses the pipe function:
      #include <unistd.h>       int pipe (int pipefd[2]);

The function creates a one-way pipeline that returns two descriptors pipefd[0], and pipefd[1],pipefd[0] for read operations, Pipefd[1] for write operations. This function generally applies communication between a parent-child process (a relational process), first a process creates a pipeline, then a subprocess, and the parent-child process can communicate through the pipeline.
Piping has the following characteristics:
The pipe is half-duplex, the data can only flow in one direction, when two sides need to communicate, need to establish two pipelines;
Can only be used between parent-child processes or sibling processes (affinity processes);
Separate form a separate file system: A pipe is a file for the process at both ends of the pipe, but it is not an ordinary file, it does not belong to a file system, but is a separate file system, and only exists in memory.
Read and write data: a process that writes to the pipeline is read out by the process at the other end of the pipeline. The content that is written is added to the end of the pipe buffer every time, and the data is read from the head of the buffer each time.


The function pipe is generally used in the following steps:
1.pipe creating pipelines;
2.fork creating sub-processes;
3. The parent-child process shuts down read and write (or write and read) descriptors, respectively;
4. Read the end on the read descriptor to start reading (or block on the read to wait for the writing end to write), write end to write, complete the parent-child process communication process.
A simple communication implementation (modified from the Linux Man Manual):

#include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <   String.h> #include <errno.h>int main (int argc, char *argv[]) {int pipefd[2];   pid_t Cpid;   Char buf[128];   int Readlen;        if (argc! = 2) {fprintf (stderr, "Usage:%s <string>\n", argv[0]);   return-1;       } if (pipe (PIPEFD) < 0) {fprintf (stderr, "Pipe:%s\n", Strerror (errno));   return-1;   } cpid = fork ();       if (Cpid < 0) {fprintf (stderr, "fork:%s\n", Strerror (errno));   return-1; if (0 = = cpid) {/* child process */close (pipefd[1]);/* Child process Close Write end */Readlen = read (Pipefd[0], buf, 128);//Sub-process blocking on read            , wait for the parent process to write if (Readlen < 0) {fprintf (stderr, "read:%s\n", Strerror (errno));       return-1;       } write (Stdout_fileno, buf, Readlen);       Write (Stdout_fileno, "\ n", 1); Close (pipefd[0]);   After reading, close the read descriptor return 0; } else {/* parent process */close (pipefd[0]);/* Parent Process shutdown uselessRead the end */sleep (2); Write (Pipefd[1], argv[1], strlen (argv[1])); The parent process begins writing close (pipefd[1]); /* The parent process closes the Write descriptor */wait (NULL);   /* The parent process waits for the child process to exit and reclaims the child process resource */return 0; }}

The runtime prints the command-line input parameters, and after the parent process sleeps for 2 seconds, the child process is blocked from reading until the parent process finishes writing the data, the visible pipeline has a synchronization mechanism and does not need to add the synchronization mechanism itself. If you want two processes to transmit data in two directions, you need to build two pipelines to implement them.
The biggest disadvantage of a pipeline is that it can only communicate between processes that have a common ancestor process, and there is no way to use it between two unrelated processes, but a well-known pipeline FIFO solves this problem. FIFO is similar to pipe, but also only one-way transmission of data, but unlike the pipe, he can communicate between unrelated processes, it provides a path associated with it, so long as the process can access the path can establish communication, similar to the previous shared memory, provides a path associated with it.
       #include <sys/types.h>       #include <sys/stat.h>       int mkfifo (const char *pathname, mode_t mode);
Pathname is the system pathname and mode is the file permission bit, similar to the second parameter of the Open function.
Opening or creating a new FIFO is called Mkfifo First, and when the specified pathname already exists, MKFIFO returns a eexist error, and the Open function is called again.
The following is the use of MKFIFO to achieve two-way communication between unrelated processes, where two FIFO is required to be used for both reading and writing. The service process loops the read and waits for the client process to write, then prints the data from the client process and returns the data to the client process; The client process writes data to the server and waits for the data returned by the service process to be read.
Server process:
#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/stat.h> #include <    sys/types.h> #include <fcntl.h> #include "slnipc.h" int main (int argc, const char *argv[]) {int rc;    int wr_fd, RD_FD;    Char sendbuf[128];    Char recvbuf[128]; rc = Mkfifo (Sln_ipc_2ser_path, O_creat | O_EXCL); Establish the service process read FIFO if (RC < 0) && (errno! = eexist)) {fprintf (stderr, "Mkfifo:%s\n", Strerror (errno))        ;    return-1; rc = Mkfifo (Sln_ipc_2clt_path, O_creat | O_EXCL); Establish the service process write FIFO if (RC < 0) && (errno! = eexist)) {fprintf (stderr, "Mkfifo:%s\n", Strerror (errno))        ;    return-1;    } wr_fd = open (Sln_ipc_2clt_path, O_RDWR, 0);        if (WR_FD < 0) {fprintf (stderr, "Open:%s\n", Strerror (errno));    return-1;    } rd_fd = open (Sln_ipc_2ser_path, O_RDWR, 0);        if (RD_FD < 0) {fprintf (stderr, "Open:%s\n", Strerror (errno));    return-1; } for (;;)    {    rc = Read (RD_FD, recvbuf, sizeof (RECVBUF));            Loop waits to accept customer process data if (RC < 0) {fprintf (stderr, "read:%s\n", Strerror (errno));        Continue        } printf ("Server recv:%s\n", recvbuf);        snprintf (sendbuf, sizeof (SENDBUF), "Hello, this is server!\n");        rc = Write (WR_FD, SendBuf, strlen (SENDBUF));            if (RC < 0) {fprintf (stderr, "write:%s\n", Strerror (errno));        Continue    }} close (WR_FD);    Close (RD_FD); return 0;}

Client process:

#include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include    <string.h> #include <errno.h> #include "slnipc.h" int main (int argc, const char *argv[]) {int rc;    int rd_fd, WR_FD;    Char recvbuf[128];    Char sendbuf[128];        if (argc! = 2) {fprintf (stderr, "Usage:%s <string>\n", argv[0]);    return-1;    } snprintf (SendBuf, sizeof (SENDBUF), "%s", argv[1]);    WR_FD = open (Sln_ipc_2ser_path, O_RDWR, 0);        if (WR_FD < 0) {fprintf (stderr, "Open:%s\n", Strerror (errno));    return-1;    } rd_fd = open (Sln_ipc_2clt_path, O_RDWR, 0);        if (RD_FD < 0) {fprintf (stderr, "Open:%s\n", Strerror (errno));    return-1;    } rc = Write (WR_FD, SendBuf, strlen (SENDBUF));        if (RC < 0) {fprintf (stderr, "write:%s\n", Strerror (errno));    return-1;    rc = Read (RD_FD, recvbuf, sizeof (RECVBUF)); if (RC < 0) {fprintf (stderr, "write:%s\n", StrerRor (errno));    return-1;    } printf ("Client read:%s\n", recvbuf);    Close (WR_FD);    Close (RD_FD); return 0;}

The server starts running and then runs the client, running the results


Here are some similar to the socket implementation interprocess communication process, only the FIFO read-write descriptor is two, the socket read and write using the same descriptor. The emergence of FIFO overcomes the communication of pipelines only between the processes that are related to each other. and other inter-process communication has been, FIFO transmission of data is also a byte stream, you need to define the protocol format to resolve the communication data, you can use the socket section described in the way to achieve the communication protocol.

Download the source code in this section:

http://download.csdn.net/detail/gentleliu/8183027


About Linux IPC (vi): Pipe and FIFO

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.