Piping (pipe)
Piping is one of the most basic IPC mechanisms by which the pipe function opens up a buffer (called a pipe) in the kernel for communication, so the pipe in the user program looks like an open file via Read (Filedes[0]), or write (filedes[1]);
int pipe (int filedes[2]);
parameters : The Filedes parameter is passed to the user program in two file descriptor tables. Filedes[0] pointing to the read end of the pipe, filedes[1] pointing to the pipe
Write End
return value : Successfully returned 0, failed to return-1
int fseek (FILE *stream, long offset, int fromwhere);
Stream : Point to Fromwhere as the benchmark
OFFSE T: Offsets offset (pointer offset) byte position
return value :
Failure: (for example, offset exceeds the size of the file itself), does not change where the stream points, the function returns a value other than 0.
Success: The stream will point to the fromwhere, offset by a byte position.
Steps for parent-child process communication:
1. The parent process creates a pipeline, opens a pipeline, and gets two file descriptors pointing at both ends of the pipeline |
650) this.width=650; "style=" width:300px;height:142px; "src=" http://s4.51cto.com/wyfs02/M00/85/69/ Wkiom1eitxjzk63maaa05prpmam904.png-wh_500x0-wm_3-wmp_4-s_2759792267.png "title=" 1.png "border=" 0 "hspace=" 0 " Vspace= "0" width= "height=" 142 "alt=" Wkiom1eitxjzk63maaa05prpmam904.png-wh_50 "/> |
2. The parent process Fork creates the child process, and the child process also has two file descriptors pointing to the same pipe |
650) this.width=650; "style=" WIDTH:350PX;HEIGHT:117PX; "src=" http://s4.51cto.com/wyfs02/M01/85/69/ Wkiom1eity-yi0amaabks3dp9te990.png-wh_500x0-wm_3-wmp_4-s_3327322265.png "title=" 2.png "border=" 0 "hspace=" 0 " Vspace= "0" width= "height=" 117 "alt=" Wkiom1eity-yi0amaabks3dp9te990.png-wh_50 "/> |
3. Parent process closes fd[0], child process closes fd[1]. The parent process can write to the pipeline, the child process can be read into the pipeline, the pipeline is implemented by the ring queue, the data flows from the writing end, read the end of the flow, which enables interprocess communication. |
650) this.width=650; "style=" width:350px;height:118px; "src=" http://s3.51cto.com/wyfs02/M02/85/69/ Wkiom1eit0ubyiccaabyj30w9b0552.png-wh_500x0-wm_3-wmp_4-s_1477188240.png "title=" 3.png "border=" 0 "hspace=" 0 " Vspace= "0" width= "height=" 118 "alt=" Wkiom1eit0ubyiccaabyj30w9b0552.png-wh_50 "/> |
The implementation mechanism inside the pipeline:
650) this.width=650; "Src=" Http://s3.51cto.com/wyfs02/M01/85/68/wKioL1eiufiCi-HiAAB_MQDSltQ008.png-wh_500x0-wm_3 -wmp_4-s_372682330.png "title=" 5.png "alt=" Wkiol1eiufici-hiaab_mqdsltq008.png-wh_50 "/>
In fact, the pipeline does not have a separate implementation of the data structure, he uses the file in Linux, but with the file structure of the filesystem and the VFS File index node inode, by the two file structure point to the same temporary VFS index node, and this VFS The index node also points to a physical page for implementation. There are two file data structures, but they define file operation routines where the address is different, one is a routine address that writes data to the pipeline, and the other is a routine address that reads data from the pipeline. In this way, the system call of the user program is still the usual file operation, but the kernel uses this abstraction mechanism to realize the special operation of the pipeline.
Test pipe capacity
Test principle: Read end not read, write end always write
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <error.h> #include < string.h> #include <sys/wait.h>int get_pipe_size (FILE*&NBSP;FD) { fseek (fd,0 , Seek_set); int start = ftell (FD); fseek (fd,0, Seek_end); int end = ftell (FD); return end - start;} Int main () { int _pipe[2]; int ret = Pipe (_pipe); if (ret == -1) { // printf ("create pipe error ,error code is:%d\n", error); return 1; } pid_t id = fork (); if (id <0) { printf ("Fork error"); return 2; } else if (id == 0) //child Turn off read- { close (_pipe[0]); int i =0; Char* _msg = null; //the writer keep writing while (1) { _msg = "R"; write (_pipe[1],_msg,strlen (_msg)); //has been writing printf ("%d\n", I); i++; } printf ("write over...\n"); } else { //father close (_pipe[1]);//close Write end char _msg[ 100]; int j =0; sleep (5); int status = 0; while (1) { status = 0; memset (_msg, ' + ', sizeof (_MSG)); printf ("%s:code id:%d\n", _msg,ret); } if (Waitpid (id,&status,0) <0) { return 3; } printf (" Status:%d\n ", (status) &0xff); } return 0;}
Test Result: approximately 64k
650) this.width=650; "style=" width:100px;height:233px; "src=" http://s1.51cto.com/wyfs02/M00/85/69/ Wkiom1eixfxgyysdaaahzynddtu043.png-wh_500x0-wm_3-wmp_4-s_3900564129.png "title=" 7.png "border=" 0 "hspace=" 0 " Vspace= "0" width= "height=" 233 "alt=" Wkiom1eixfxgyysdaaahzynddtu043.png-wh_50 "/>
Ipc-Pipeline Communication