Inter-process communication (IPC mechanism) - pipeline

1. Introduction of the pipeline

Pipes are inter-process communication tools, including unnamed pipes and named pipes. The former is popular in parent-child processes, and the latter can be shared by unrelated processes because it can exist independently as a disk file. The pipeline is a queue-type data structure. Its data is input from one end and output from the other end. Its most common application is to connect the input and output of two processes, that is, to use the output of one process as the input of another process.

2. Famous pipeline

Well-known pipes can communicate between any two processes.

1. Creation of a well-known pipeline:

Creation of named pipes :

  1. Command to create: mkfifo + pipe name
  2. system call creation

Header files needed to create named pipes : fcntl

2. Examples of using well-known pipes:

The data obtained by process a from the keyboard is passed to another process b in a loop.
We can use to create a file, a gets the string from the keyboard and stores it in the file, and b reads it from the file. But the file is stored on the disk, the speed is not as fast as the pipeline, and it will not wait if it cannot read data from the file, but the pipeline is different. If b cannot read data from the pipeline, it will block until a writes data to the pipeline again.

Write side:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>
#include<sys/stat.h>

int main()
{
    
    
    int fd = open("fifo",O_WRONLY);
    assert(fd != -1);
    printf("open FIFO success\n");

    while(1)
    {
    
    
        printf("please input:\n");

        char buff[128] = {
    
    0};
        fgets(buff,128,stdin);
        write(fd,buff,strlen(buff)-1);

        if(strncmp(buff,"end",3)==0)
        {
    
    
            break;
        }
    }

    close(fd);
    exit(0);
}

Read end:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>
#include<sys/stat.h>

int main()
{
    
    
    int fd = open("fifo",O_RDONLY);
    assert(fd != -1);
    printf("FIFO open success\n");

    while(1)
    {
    
    
        char buff[128] = {
    
    0};
        int n = read(fd,buff,127);

        if(n <= 0 || (strncmp(buff, "end", 3)==0))
        {
    
    
            break;
        }
        printf("%s\n",buff);
    }

    close(fd);
    exit(0);
}


(1) If the read or write end is opened first, it will be blocked at open until the other end also opens the pipe.
(2) After both the write end and the read end are opened, the read end will block at read, and after the write end writes data into the pipeline, the read end will normally execute read, and continue to block at read after execution.
(3) If the read end is closed, the write end will trigger a signal (SIGPIPE) to exit automatically after inputting data to the pipeline.
(4) If the write end is closed, the read function value of the read end will return 0.

3. Anonymous pipeline

Unnamed pipes are mainly used for communication between parent and child processes.

1. Creation of unnamed pipes

Use pipe() to create an unnamed pipe. Successful creation returns 0, and failure returns -1.
fds[0] is the descriptor of the read end of the pipe
fds[1] is the descriptor of the write end of the pipe

2. Examples of the use of unnamed pipes

code:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>

int main()
{
    
    
    int fd[2];
    int res = pipe(fd);
    assert(res != -1);


    pid_t pid = fork();
    assert(pid != -1);

    if(pid == 0)
    {
    
    
    	close(fd[1]);
        char buff[128] = {
    
    0};
        read(fd[0],buff,127);
        printf("child read:%s\n",buff);
        close(fd[0]);
    }
    else
    {
    
    
    	close(fd[0]);
        char buff[128] = {
    
    0};
        printf("please input(less 128):\n");
        fgets(buff,128,stdin);
        write(fd[1],buff,strlen(buff)-1);
        close(fd[1]);
    }
    
    exit(0);
}

4. Realization of the pipeline

insert image description here
Writes start from the head pointer, and reads start from the tail pointer. After writing, the head pointer moves, and after reading, the tail pointer moves.
If the head pointer catches up with the tail pointer, then the pipe is full and the write will be blocked. If the tail pointer catches up with the head pointer, then the pipe is empty and read blocks.

5. Related interview questions

  1. What is the communication method of the pipe? How do you understand that pipelines are this kind of communication?
    The communication mode of the pipeline is half-duplex communication;
    since one command in Linux can only complete one function, a complex task requires several processes to complete cooperatively, and the processing result of the first process needs to be handed over to the second process, and then the communication will be completed once. For the third one, wait, just like the assembly line to complete the production of a certain product, this process only requires data to be transmitted in one direction, so it was designed as half-duplex.
    Of course, you can also use pipes to achieve duplex communication, which requires two pipes.

  2. What are the three communication methods? What are the differences?
    Simplex communication: There is only one direction of transmission, and simplex communication has only one data line, and it only works in one direction, such as printers, TVs, etc.
    Half-duplex communication: Two-way communication is possible, but it can only be transmitted in turn, and there is only one data line, which is different from simplex communication in that this data line can be used as both sending and receiving, although data can be uploaded in two directions send, but the communicating parties cannot send and receive data at the same time.
    Full-duplex communication: Data can be transmitted in both directions at the same time. Two different data lines are used for data transmission and reception. Both parties in the communication can send and receive at the same time, and the transmission and reception are carried out simultaneously without delay.

  3. What is the difference between a named pipe and an unnamed pipe?
    Well-known pipes can communicate between any two processes.
    Unnamed pipes can only communicate between parent and child processes.

  4. Where is the data written to the pipe stored?
    Data written to the pipeline is stored in memory.

Guess you like

Origin blog.csdn.net/weixin_56935264/article/details/125086591