Let's start by talking about the general purpose of interprocess communication (IPC), such as data transfer, shared data, notification events, resource sharing, and process control. But we know that for each process the process sees a piece of memory that belongs to it, and this resource is exclusive, so communication between processes can be cumbersome, and the principle is that a common resource can be seen between different processes. so the exchange of data must be through the kernel, in the kernel to open up the block buffer, process 1 to the data from the user space to the kernel buffer, process 2 and then read the data from the kernel buffer, the kernel provides this mechanism is called inter-process communication. In general, we use inter-process communication methods that have
- Piping (pipe) and well-known piping (FIFO)
- Signal (signal)
- Message Queuing
- Shared memory
- Signal Volume
- Socket (socket)
Let's start with the simplest form of communication.
Anonymous piping pipe
--------------------------------------------------------------------------------------------------------------- ------------------
Creation of pipelines
Pipeline is one of the most basic inter-process communication mechanisms. Pipelines are created by the pipe function:
Calling the pipe function creates a buffer in the kernel for interprocess communication, a buffer called a pipe that has a read end and a write end.
The pipe function accepts a parameter, which is an array of two integers, if the call succeeds, it passes through pipefd[2] to the user program two file descriptor, note that PIPEFD [0] points to the read end of the pipe, PIPEFD [1] points to the write end of the pipe, So at this point the pipeline is a file for the user program, which can be done via read (PIPEFD [0]) or write (PIPEFD [1]). The pipe function call successfully returns 0, otherwise returns-1.
Then take a look at the steps to communicate through the pipeline:
"The parent process creates a pipeline that gets two file descriptors pointing at both ends of the pipe
"Using the fork function to create a child process, the child process also gets two file descriptors pointing to the same pipe
"Parent process closes the read end (Pipe[0]), the child process closes the write end pipe[1], then the parent process can write to the pipeline, the child process can be read from the pipeline, thus implementing interprocess communication through the pipeline.
Example code:
#include <stdio.h> #include <unistd.h> #include <string.h>int main () {int _pipe[2];int ret=pipe (_pipe ); if (ret<0) { perror ("pipe\n"); } pid_t id=fork (); if (id<0) { perror ("fork\n"); } else if (id==0) //child { close (_pipe[0]); int i=0; char *mesg=null; while (i<100) { mesg= ' I am child '; Write (_pipe[1],mesg,strlen (MESG) +1); Sleep (1); ++i; } } else //father { close (_pipe[1]); int j=0; Char _mesg[100]; while (j<100) { memset (_MESG, ' n ', sizeof (_MESG)); Read (_pipe[0],_mesg,sizeof (_MESG)); printf ("%s\n", _MESG); j + +; } } return 0;}
Results Demo:
Features of pipe:
1. One-way communication only
2. Communication only in the process of blood relations
3. Dependent on the file system
4. Life cycle with process
5. Byte-stream-oriented services
6. The internal pipeline provides a synchronization mechanism
Note: Because the pipeline communication is one-way, in the above example we are through the child process to write the parent process to read, if you want the parent process to write while the child process to read, you need to open another pipeline;
The read-write end of the pipeline is passed through the open-piece descriptor, so that the two processes to communicate must inherit the pipeline from their common ancestor. What is the process of passing the description of the. Communication between processes, or can it? Process Fork two times, pass the???????????????????????
Four Special cases:
"If all of the code points that point to the end of the pipeline are closed, and there is still a process reading the data from the read end of the pipeline, then the remaining data in the pipeline is read, and read again returns 0, just like the end of the piece?
"If there is a line to the end of the pipe write-off,?" The process that holds the write end of the pipeline does not write data to the pipeline, and the process reads the data from the pipe, and then the remaining data in the pipeline is read, and then read is blocked until the data is readable in the pipeline and returned.
If all of the sigpipe that point to the end of the pipe are closed, then there is a process pointing to the write-side of the pipeline, then the process receives a signal, which usually causes the process to end unexpectedly.
If there is a reference to the pipe read end of the description of the package is not closed? The process that holds the write end of the pipeline does not read the data from the pipeline, and then the process writes the data to the pipe write, then the write will block when the pipeline is full, until the pipeline has empty position to write? data and return.
Named pipe FIFO
--------------------------------------------------------------------------------------------------------------- ------------------
In a pipeline, only a blood-related process can communicate, and for later named pipes, this problem is resolved. The FIFO differs from the pipeline in that it provides a path name associated with it and is stored in a FIFO form in the system. A named pipe is a device? So, even if the process is not related to the process that created the FIFO, as long as the path can be accessed, it can communicate with each other through the FIFO. It is important to note that the FIFO (first input output) is always in accordance with the principle of LIFO, the first written data will be read out of the pipeline first.
Named Pipes are created
There are two system functions that create a named pipe: Mknod and Mkfifo. Two functions are defined in the head piece sys/stat.h,
The function prototypes are as follows:
#include <sys/types.h>
#include <sys/stat.h>
int Mknod (const char *path,mode_t mod,dev_t dev);
int Mkfifo (const char *path,mode_t mode);
The function Mknod parameter in path is the full pathname of the named pipe that was created: MoD for the named pipe created for the modulo finger
The device value, which depends on the type of creation of the piece, which will only be made when the device is created. Both of these functions return 0, and the failure returns-1. The Mknod function creates a named pipe:
Umask (0);
if (Mknod ("/tmp/fifo", S_ififo | 0666) = =-1)
{
Perror ("Mkfifo error");
Exit (1);
}
function Mkfifo The meaning of the first two parameters is the same as Mknod. What's the Mkfifo? Example code:
Umask (0);
if (Mkfifo ("/tmp/fifo", s_ififo|0666) = =-1)
{
Perror ("Mkfifo error!");
Exit (1);
}
"S_ififo|0666" indicates that a named pipe is created with access permission of 0666, which is the creator, the same group as the creator
The user and other users access to the named pipe is readable and writable (this? Note that Umask
The impact of the pipe-to-part permissions).
Named pipes are created so that you can make them, named pipes and pipes. The law is basically the same. It's just the life.
The name of the pipe, you must first set it open (). Because a named pipe is a. piece that exists on the hard disk, pipe
is a special piece that exists in memory.
It is important to note that the process of opening a named pipe may be blocked by the tune Open (). But what if at the same time? Read-Write
(O_RDWR) is turned on, it will not cause blocking, if opened with read-only (o_rdonly), the
? Open ()
Run the sample
-----------------------------------------------------------
So at this point we server.c to create a named pipe and open it, write to the pipeline, read in the client.c, and print the read content, so we can use named pipe communication.
SERVER.C: #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <string.h># include<sys/stat.h> #include <fcntl.h> #define _PATH_NAME_ "/tmp/file.tmp" #define _SIZE_ + int main () { int Ret=mkfifo (_path_name_,s_ififo|0666); if (ret==-1) {printf ("Make FIFO error\n"); return 1; } Char Buf[_size_]; memset (buf, ' n ', sizeof (BUF)); int Fd=open (_path_name_,o_wronly); while (1) {//scanf ("%s", buf); Fgets (buf,sizeof (BUF) -1,stdin); int Ret=write (Fd,buf,strlen (BUF) +1); if (ret<0) {printf ("write error"); Break }} close (FD); return 0; } client.c: #include <stdio.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h > #include <sys/types.h> #include <string.h> #define _PATH_NAME "/tmp/file.tmp" #define _SIZE_ int Main () {int fd=open (_path_name,o_rdonly); if (fd<0) {printf ("Open file Error"); return 1; } Char Buf[_size_]; memset (buf, ' n ', sizeof (BUF)); while (1) {int Ret=read (fd,buf,sizeof (BUF)); if (ret<0) {printf ("read end or error\n"); Break } printf ("%s", buf); } close (FD); return 0; }
Results Demo:
You can see that I am actually sending "Hello" "I am Aerver" on the server, and the client can receive this content and complete simple interprocess communication.
Pipeline for interprocess communication (pipe, FIFO)