Pipeline of interprocess communication

Source: Internet
Author: User
Tags readable

First of all, why do we need to communicate between processes?

Each process has its own user address space, no one can see the data of other processes, sometimes the process to exchange data with each other, so it is necessary to open a buffer in the kernel, process 1 write data to the buffer, process 2 and then read the data from the buffer, so that the process of communication between

650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M01/7E/D4/wKiom1cJrQLjfrE2AAAvacqHvVE820.png "title=" Ipc.png "alt=" Wkiom1cjrqljfre2aaavacqhvve820.png "/>

Piping (pipe) is the most basic interprocess communication (IPC) mechanism, created by the pipe () function

#include <unistd.h>

The prototype is: int pipe (int pipefd[2])


Pipe () in the kernel to open a buffer (pipe), to the array pipefd[2] return two non-negative small integer, that is, the file descriptor, point at both ends of the buffer, pipefd[0] for the read end, Pipefd[1] as the write end, write to the file by writing the data equivalent to the buffer to write data, Reading data from a file through the read-through is the data from the buffer.

Pipe () Create pipeline successfully returns 0, failure returns-1.

The buffer is in memory.


Communication steps:

    1. The parent process calls pipe () to create the pipeline, and if successful, returns two file descriptors, pointing to both the read and write ends

    2. The parent process fork out a child process that replicates all the characteristics of the parent process, that is, both the read and write ends of the child process point to the same buffer

    3. The parent process closes the write end (Close (pipefd[1]), and the child process closes the read end (Close (pipefd[0)), so that the process can be written to the pipeline, and the parent process can read from the pipe



Pipelines can overcome two problems with using files for communication, as follows:  

1. Limit the size of the pipe.

2. The read process may also work faster than the write process. When all current process data has been read, the pipeline becomes empty. When this happens, a subsequent read () call will be blocked by default, waiting for some data to be written, which resolves the issue where the read () call returns the end of the file.



the pipeline is implemented with a circular queue .

In essence, pipelines are also a kind of file, but it is different from ordinary files, it is a fixed size buffer, limit the size of the file, and not like other files without the unrestricted growth of testing, Linux under the size of the buffer is a page, that is, 4K bytes (2^12)


There is no ring structure in memory, it is implemented by the linear space of the array, and when the data reaches the end of the array, it is returned to the head for processing, and this reversal is performed by the modulo operation.

This ring queue is actually the array q[0] and q[maxn-1] together to form, here MAXN is the maximum length of the array

650) this.width=650; "src=" Http://s1.51cto.com/wyfs02/M02/7E/D1/wKioL1cJtxXBayvUAAC_hbEtgKM806.png "title=" Ring queue. png "alt=" Wkiol1cjtxxbayvuaac_hbetgkm806.png "/>


The head points to a readable position, and the tail points to the writable location where the empty space between them is available.

Reading data from the pipeline is a one-time operation, once the data is read, it is discarded to hold more data, from the point of reading the data after the head pointer moves backwards, so that the available space will increase.


Code Implementation four cases of pipeline communication: (All of the following are child process write parent process Read)

1. All the file descriptors pointing to the read end are closed (the Read reference count is 0), and the process writes to the write end, the process will receive a signal sigpipe, and the write end will stop writing.

#include <stdio.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> #include < String.h>int main () {    int pipefd[2];    int res= Pipe (PIPEFD);     if (res==-1) {        perror ("pipe") );        return 1;    }     else{        pid_t id=fork ();         if (id<0) {            perror (" Fork ");             exit (1);         }        else if (id==0) {//child             close (pipefd[1]);             int count=10;             char str[100];            while (count) {                 memset (str, ' ', sizeof (str));                 int _size=read (pipefd[0],str,sizeof (str));                 printf ("size:%d,str:%s\n", _size,str);                 count--;             }             Close (Pipefd[0]);        }         else{//father            close (pipefd[0]);             int count=15;             char* str=NULL;             while (count) {                 str= "hello world!";                 write (pipefd[1 ],str,strlen (str) +1);                 sleep (1);                 count--;            }         }    }    return 0;}

The results of the operation are as follows:

650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M00/7E/D6/wKiom1cJ-4fSdiowAAAS_Yg38z8156.png "title=" 1.png " alt= "Wkiom1cj-4fsdiowaaas_yg38z8156.png"/>

2. If there is a file descriptor pointing to the end of the pipe is not closed (the reference count of the pipe read is greater than 0), and the process that holds the pipe read does not read the data from the pipe, then there is a process to write the data to the pipe, then write will block when the pipeline is full, until there is empty position in the pipeline

#include <stdio.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> #include < String.h>int main () {    int pipefd[2];    int res= Pipe (PIPEFD);     if (res==-1) {        perror ("pipe") );        return 1;    }     else{        pid_t id=fork ();         if (id<0) {            perror (" Fork ");             exit (1);         }        else if (id==0) {//child             close (pipefd[1]);             int count=1000;             sleep (5);            char str[100];             while (1) {                 if (count) {                     memset (str, ' ', sizeof (str));                     int _size=read (pipefd[0],str,13);                     printf ("size:%d,str:%s\n", _size, STR);                     count--;                }             }        }         else{//father             close (pipefd[0]);             char* str=null;            int i=0;             while (1) {                 str= "hello world!";                 write (pipefd[1 ],str,strlen (str) +1);                 //sleep (1); &NBSP;&NBSP;&NBSP;&NBsp;            i++;                  printf ("i=%d  ", i);             }         }    }    return 0;}

The results of the operation are as follows:

650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M00/7E/D7/wKiom1cKAimAx2jyAAAd5X3b6S4471.png "style=" float: none; "title=" 1.png "alt=" Wkiom1ckaimax2jyaaad5x3b6s4471.png "/>


650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M00/7E/D3/wKioL1cKAtuTnBtaAABSOC66npA540.png "style=" float: none; "title=" 2.png "alt=" Wkiol1ckatutnbtaaabsoc66npa540.png "/>

When the parent process writes data, the child process is not running, the pipeline is full, write blocks, and when the child process reads the data stepfather the process begins to write the data.


3. If all the file descriptors pointing to the write end are closed, but there is still a process reading the data from the read end, when the data in the pipeline is all read, read returns 0 as if the end of the file is read

#include <stdio.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> #include < String.h>int main () {    int pipefd[2];    int res= Pipe (PIPEFD);     if (res==-1) {        perror ("pipe") );        return 1;    }        else{        pid_t id=fork ();         if (id<0) {             perror ("fork");             return  1;        }        else  if (id==0) {//child            close (pipefd[1] );             int count=10;             char str[100];             while (count) {                 memset (str, ' + ', sizeof (str));                 int _size=read (pipefd[0],str,sizeof (str));                 printf ("size:%d,str:%s\n", _size,str);                 count--;             }        }         else{//father              Close (pipefd[0]);            int count=5;             char* str=NULL;             while (count) {                 str= "hello world!";                 write (pipefd[1 ],str,strlen (str) +1);                 sleep (1);                 count--;            }             close (pipefd[1]);         }    }       return 0;} 

Operation Result:

650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M00/7E/D4/wKioL1cKBQWCaLZCAAAVZb5QsGo268.png "title=" 1.png " alt= "Wkiol1ckbqwcalzcaaavzb5qsgo268.png"/>


4. If the file descriptor pointing to the write end is not closed, but is not written, the process reading the data from the read end will be blocked until the write end writes the data again

#include <stdio.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> #include < String.h>    int main () {    int pipefd[2];     int res=pipe (PIPEFD);     if (res==-1) {         perror ("pipe");        return 1;     }       else{        pid_t  id=fork ();         if (id<0) {             perror ("fork");             exit (1);        }         else if (id==0) {//child             close (pipefd[1]);             int count=10;             char str[100];             while (count) {                 memset (str, ' + ', sizeof (str));                 int _size=read (pipefd[0],str,sizeof (str));                 printf ("size:%d,str:%s\n", _SIZE,STR);                 count--;            }         }        else{//father              close (pipefd[0]);             char* str=null;            int count=10;             while (count) {                 if (count==5) {                     printf ("I  just want to sleep!\n ");                     sleep (5);                 }                 str= "hello world!";            &nBsp;    write (Pipefd[1],str,strlen (str) +1);                 sleep (1);                 count--;             }        }    }     return 0;}

Operation Result:

650) this.width=650; "src=" Http://s1.51cto.com/wyfs02/M00/7E/D4/wKioL1cKBu7R65qYAAARvuhWeK4940.png "style=" float: none; "title=" 1.png "alt=" Wkiol1ckbu7r65qyaaarvuhwek4940.png "/>

650) this.width=650; "src=" Http://s1.51cto.com/wyfs02/M01/7E/D7/wKiom1cKBjzSl4VVAAAXtem5x58688.png "style=" float: none; "title=" 2.png "alt=" Wkiom1ckbjzsl4vvaaaxtem5x58688.png "/>


When no data is readable in the pipeline (count==5 sleep), read blocks until the write end writes the data again

This article is from the "Zero Egg" blog, please be sure to keep this source http://lingdandan.blog.51cto.com/10697032/1762335

Pipeline of interprocess communication

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.