Each process has a different user address space, the global variables of any one process can not be seen in another process, so the process to exchange data between the kernel, the kernel to open a buffer, process 1 data from the user space to the kernel buffer, process 2 and then read the data from the kernel buffer, This mechanism provided by the kernel is called interprocess communication (ipc,interprocess communication). As shown in.
<a href= "http://www.emacsvi.com/wp-content/uploads/2015/10/IPC_pipe_ie.jpg" ></a>
Piping is the most basic IPC mechanism, created by the pipe function:
<pre lang= "C" escaped= "true" >
#include <unistd.h>
int pipe (int pipefd[2]);
</pre>
Call the pipe function in the kernel to open a buffer (called a pipe) for communication, it has a read end of a write end, and then passed through the Filedes parameter to the user program two file descriptor, Filedes[0] point to the read end of the pipe, filedes[1] point to the write end of the pipeline (very good remember, Just like 0 is standard input 1 is the same as standard output). So the pipeline in the user program looks like an open file, through Read (Filedes[0]), or write (filedes[1]); Reading and writing data to this file is actually reading and writing the kernel buffer. The pipe function call successfully returned 0, and the call failed to return-1.
The two file descriptors in <blockquote>int pipe (int filedes[2]) are mandatory filedes[0] can only point to the read end of the pipe, and if a write occurs, the error will occur; Filedes[1] can only point to the write end of the pipe. If the read operation occurs, an error .</blockquote>
How can communication between two processes be realized after the pipeline is opened? For example, you can follow the steps below to communicate.
<a href= "http://www.emacsvi.com/wp-content/uploads/2015/10/IPC_pipe.jpg" ></a>
<ol>
The <li> parent process calls pipe to open a pipeline and gets two file descriptors pointing at both ends of the pipeline. </li>
<li> parent process calls fork to create a child process, the child process also has two file descriptors pointing to the same pipeline. </li>
<li> parent Process closes the pipe read end, and the child process closes the pipe write end. The parent process can write to the pipeline, the child process can be read from the pipeline, the pipeline is implemented by the ring queue, the data flows from the writing end flow from the reading end, so that the process of communication between. </li>
</ol>
Note: Never understand why the parent process here to shut down the pipe read end, and the child process to close the pipe write end, think for a long time finally figured out ..., for the following reasons: Because this program is to simulate the parent process and the child process of the pipeline read and write operations, where the parent process to write data to the pipeline, The child process is used to read data to the pipeline, so start to close the parent process's read file descriptor Filedes[0], and close the child process's write file descriptor filedes[1], which is to simulate this process.
Then as to why the parent process closes the read file descriptor of the pipe filedes[0] the child process can also read the data of the pipeline because the system maintains a count of the file descriptor of a file, the parent-child process each has a file descriptor pointing to the same file, and when a file descriptor is closed, the corresponding count is reduced by one, When this count is reduced to 0 o'clock, the file is closed, so although the parent process closes its file descriptor Filedes[0], the file descriptor count is not equal to 0, so the child process can also be read. It can also be understood that both the parent and child processes have their own file descriptors, so although Filedes[0] is closed in the parent process, filedes[0 in the child process does not affect
Each item in the File table maintains a reference count that identifies how many file descriptor (FD) references the table entry will be deleted when the reference count is 0. So calling Close (FD) closes the file descriptor of the child process, only reduces the reference count, but does not cause the file table entry to be purged, so the parent process can still access
Finally, it is important to note that, under the pipe pipeline of Linux, when writing data on the writing end, the buffer file of the read end is not required (i.e., the file descriptor count of 0 is not required), but the buffer file of the write end must be closed (that is, the write end's file descriptor count is 0) before reading the data.
<pre lang= "C" escaped= "true" >
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main (int argc, char *argv[])
{
int pipefd[2];
pid_t Cpid;
Char buf;
if (argc! = 2) {
fprintf (stderr, "Usage:%s <string>\n", argv[0]);
Exit (Exit_failure);
}
if (pipe (PIPEFD) = =-1) {
Perror ("pipe");
Exit (Exit_failure);
}
Cpid = fork ();
if (cpid = =-1) {
Perror ("fork");
Exit (Exit_failure);
}
if (Cpid = = 0) {/* child reads from PIPE */
Close (pipefd[1]); /* Close Unused write end */
while (read (pipefd[0], &buf, 1) > 0)
Write (Stdout_fileno, &buf, 1);
Write (Stdout_fileno, "\ n", 1);
Close (pipefd[0]);
_exit (exit_success);
} else {/* Parent writes ARGV[1] to pipe */
Close (pipefd[0]); /* Close Unused read end */
Write (Pipefd[1], argv[1], strlen (argv[1]));
Close (pipefd[1]); /* Reader'll see EOF */
Wait (NULL); /* Wait for child */
Exit (exit_success);
}
}
</pre>
<ol>
<li> two processes through a pipeline can only achieve one-way communication, such as the above example, the parent process write sub-process read, if sometimes also requires the child process to write the parent process read, you must open another pipeline. Ask the reader to think, if only one pipeline, but the parent process does not shut down the read end, the child process does not shut down the write end, both sides have read and write end, why can not achieve two-way communication? </li>
The read-write side of the <li> pipeline is passed through an open file descriptor, so the two processes to communicate must inherit the pipe file descriptor from their common ancestor. The above example is the parent process to pass the file descriptor to the child process communication between the parent and child processes, can also fork two times the parent process, the file descriptor to two sub-processes, and then two sub-processes to communicate, in short, you need to pass the file descriptor by fork so that two processes can access the same pipeline, they can communicate. <li></ol>
There are 4 special cases that you need to be aware of in the pipeline (assuming all blocking I/O operations and not setting the O_NONBLOCK flag):
1. If all the file descriptors that point to the pipe write end are closed (the reference count for the pipe write is equal to 0), and there is still a process reading the data from the read end of the pipeline, the remaining data in the pipeline is read, and read again returns 0, just like the end of the file.
2. If there is a file descriptor pointing to the end of the pipe is not closed (the reference count of the pipe write end is greater than 0), and the process that holds the pipe write end does not write data to the pipeline, then there is a process reading the data from the pipe, then the remaining data in the pipeline is read, again read will block, The data is read and returned until the data in the pipeline is readable.
3. If all the file descriptors pointing to the pipe read end are closed (the reference count for the pipe read is equal to 0), then there is a process to write to the pipeline, then the process receives the signal sigpipe, which usually causes the process to terminate unexpectedly. In the 33rd chapter the signal will talk about how to make the sigpipe signal do not terminate the process.
4. If there is a file descriptor pointing to the read 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 pipeline, then write again when the pipe is full and then block until there is empty position in
These four special cases of pipelines have universal significance. In the 37th chapter of the socket programming the TCP socket to speak also has these features of the pipeline.
The most basic IPC mechanism of pipe () piping