Comunicación entre procesos de Linux: canalización (activada)

Tabla de contenido

Preámbulo

1. Introducción a la comunicación entre procesos

En segundo lugar, ¿qué es un oleoducto?

Tres, el principio básico de la tubería.

3.1 Tuberías anónimas

3.2 Fundamentos de las tuberías

Cuatro, código de muestra

5. Reglas de lectura y escritura de canalización

Seis, las características de la tubería.

Resumir


Preámbulo

Este artículo explica principalmente el contenido principal de la tubería en la comunicación entre procesos, como el principio básico, el código de muestra y las características, etc.

1. Introducción a la comunicación entre procesos

En primer lugar, la comunicación entre procesos se refiere a la difusión o intercambio de información entre diferentes procesos . Como todos sabemos, en Linux, cada proceso es independiente entre sí, lo que dificulta la comunicación independiente entre procesos, por lo que los procesos quieren comunicar La comunicación requiere la ayuda de un tercero, que también puede considerarse como un medio para la comunicación entre procesos. En el desarrollo de la comunicación entre procesos, se utilizan los siguientes tres medios principales: canalizaciones, comunicación entre procesos System V, y comunicación entre procesos POSIX

El propósito principal de la comunicación entre procesos es el siguiente

Transferencia de datos: un proceso necesita enviar sus datos a otro proceso
Uso compartido de recursos: el mismo recurso se comparte entre varios procesos.
Evento de notificación: un proceso necesita enviar un mensaje a otro proceso o grupo de procesos, informándole (ellos) que se ha producido algún evento (como notificar al proceso principal cuando finaliza el proceso).
Control de procesos: algunos procesos quieren controlar completamente la ejecución de otro proceso (como el proceso de depuración). En este momento, el proceso de control espera poder interceptar todas las trampas y excepciones de otro proceso y poder conocer su estado. cambios en el tiempo.

Este artículo explica principalmente la tubería en la comunicación entre procesos.

En segundo lugar, ¿qué es un oleoducto?

  • Las tuberías son la forma más antigua de comunicación entre procesos en Unix.

  • Llamamos "tubería" a un flujo de datos de un proceso a otro.

     

    Como se indicó anteriormente, el comando who | wc -l es un uso simple de la canalización. El contenido ejecutado por el proceso who se pasa a la canalización, y luego el proceso wc lee el contenido de la canalización y completa sus propias funciones, de modo que los dos procesos no se destruyen En el caso de la independencia, el mismo recurso (es decir, el contenido que muestra el comando who) se ve a través de la canalización para completar la comunicación entre procesos.

Tres, el principio básico de la canalización anónima.

En primer lugar, las canalizaciones se dividen principalmente en canalizaciones anónimas y canalizaciones con nombre, y utilizamos canalizaciones anónimas para explicar los principios de las canalizaciones y sus códigos de muestra.

3.1 Tuberías anónimas

En primer lugar, una canalización anónima se refiere a una canalización sin nombre creada con la función de canalización.Los archivos de encabezado necesarios y los prototipos de función son los siguientes

#include <unistd.h>
int pipe(int fd[2]);

parámetro

fd: matriz de descriptores de archivo, donde fd[0] representa el final de lectura, fd[1] representa el final de escritura
Valor de retorno: devuelve 0 en caso de éxito, devuelve un código de error en caso de falla

Por lo tanto, a partir de la matriz de descriptores de archivos anterior y del principio de que todo es un archivo en Linux, podemos deducir que las tuberías también son archivos.

3.2 Fundamentos de las canalizaciones anónimas

La implementación de la canalización se basa principalmente en la bifurcación para compartir la canalización. El proceso principal es el siguiente (a continuación se describen todas las canalizaciones desde la perspectiva de los descriptores de archivo ):

 1. El proceso principal crea una canalización

 Como se muestra arriba, el proceso principal primero crea una canalización con la función de canalización, fd[0] (que corresponde a 3 en la tabla de descriptores de archivos) corresponde a la canalización de lectura, y fd[1] (corresponde a 4 en la tabla de descriptores de archivos ) corresponde a la canalización de escritura

 2. El proceso padre bifurca al proceso hijo

 Como se muestra arriba, el proceso secundario bifurcado por el proceso principal hereda la tabla de descriptores de archivo del proceso principal (tenga en cuenta que esta es una copia superficial, por lo que el proceso secundario no crea una nueva canalización), por lo que fd[0], fd[ 1] del proceso secundario El contenido señalado es coherente con el proceso principal.

3. Los procesos padre e hijo cierran fds innecesarios respectivamente (aquí tomamos como ejemplo la escritura del proceso padre y la lectura del proceso hijo, y los escenarios de uso se utilizan principalmente en uso, y no hay necesidad de ceñirse a la escritura y el proceso padre). niño leyendo)

 Como se muestra en la figura anterior, cuando el proceso principal escribe, cerrará fd[0] y el proceso secundario cerrará fd[1] cuando lea.Desde entonces, el proceso principal puede ver el mismo recurso a través de la canalización, y luego se puede usar sin destruir la comunicación del proceso con independencia del proceso

Por lo tanto, de hecho, los tres pasos anteriores pueden considerarse como un esquema de comunicación para permitir que los procesos padre e hijo vean el mismo recurso y se comuniquen.

Cuatro, código de muestra

Se ha explicado el principio básico de la tubería anónima. A continuación, completamos el código de muestra de acuerdo con el principio anterior y realizamos experimentos relacionados a través del código de muestra para explorar más a fondo la naturaleza y las características de la tubería. El código de muestra es el siguiente

#include <iostream>
#include <unistd.h>
#include <cerrno>
#include <string>
#include <cassert>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
using namespace std;

int main()
{
    //1.创建管道
    int mypipe[2]={0};
    int n=pipe(mypipe);
    if(n<0)//创建失败报错返回
    {
        cout<<"pipe error: "<<errno<<":"<<strerror(errno)<<endl;
        return 1;
    }

    cout<<"mypipe[0]: "<<mypipe[0]<<endl;//[0]-0-张嘴读
    cout<<"mypipe[1]: "<<mypipe[1]<<endl;//[1]-1-用笔写

    //2.创建子进程
    pid_t fd=fork();
    assert(fd!=-1);//判断创建是否成功

    //子进程
    if(fd==0)
    {
        //3.父进程写入,子进程读取
        close(mypipe[1]);

        //4.通信
        char buffer[1024];
        while(true)
        {
            int n=read(mypipe[0],buffer,sizeof(buffer)-1);
            
            if(n>0)
            {
                buffer[n]='\0';
                cout<<"我是子进程,父进程给我的讯息是: "<<buffer<<endl;
            }
            
        }

        //退出
        close(mypipe[0]);
        exit(0);

    }

    //父进程
    //3.父进程写入,子进程读取
    close(mypipe[0]);
    
    //4.通信
    const string str=("hello,我是父进程");
    int cur=1;
    char buffer[1024];
    while(true)
    {
        sleep(1);//写入等待一秒

        snprintf(buffer,sizeof(buffer),"%s,计数器:%d,我的pid:%d",str.c_str(),cur++,getpid());
        write(mypipe[1],buffer,strlen(buffer));
        
    }


    close(mypipe[1]);
    return 0;
}

 El resultado de la operación es el siguiente

 

5. Reglas de lectura y escritura de canalización

1. Cuando no hay datos para leer, si la otra parte no envía, solo podemos esperar

 Como se muestra en la figura anterior, cuando la escritura está configurada para escribir cada cinco segundos, el lector dejará de ejecutarse y esperará a que se escriban los datos después de la lectura.

 2. Cuando la tubería está llena, no puede continuar escribiendo

 Como se muestra en la figura anterior, continuamos escribiendo la letra a en el lado de la escritura, y usamos cur para registrar el número de letras a, y luego el lado de lectura se lee una vez cada 10. Descubrimos que antes de la primera lectura, cur es 65536 , es decir, se deberían escribir 65536 letras a, pero de hecho encontramos que cuando el pipeline está lleno, no escribirá

3. Si el extremo de escritura está cerrado, después de leer los datos de la canalización, la lectura de nuevo devolverá 0, lo que indica que la lectura ha terminado.

 Como se muestra en la figura anterior, después de que dejamos de escribir, la canalización vuelve a leer, el valor de retorno de read es 0 y la lectura finaliza.

4. El extremo de escritura sigue escribiendo y el extremo de lectura se ha cerrado. En este momento, el comportamiento del extremo de escritura no tiene sentido. El sistema operativo no permitirá un comportamiento sin sentido, baja eficiencia y desperdicio de recursos, por lo que eliminará la escritura. end y enviarlo a través de una señal.terminación.

 Como se muestra en la figura, cuando finaliza la lectura, es decir, el proceso secundario deja de leer, el sistema operativo elimina directamente el final de la escritura, es decir, el proceso principal.

5. Cuando la cantidad de datos a escribir no supere la capacidad del pipeline, Linux garantizará la atomicidad de la escritura: cuando la cantidad de datos a escribir sea superior a la capacidad del pipeline, Linux ya no garantizará la atomicidad de la escritura

En otras palabras, cuando la cantidad de datos escritos es menor que la capacidad de la canalización, Linux puede garantizar la exactitud de los datos, de lo contrario, los datos pueden distorsionarse.

Seis, las características de la tubería.

Del contenido anterior, la tubería de valor que podemos tener tiene las siguientes características

1. Comunicación unidireccional, es decir, su flujo de datos solo puede fluir en una dirección

2. La esencia de la tubería es el archivo, y debido a que el ciclo de vida de fd (operador de archivos) termina con el final del proceso, el ciclo de vida de la tubería también termina con el final del proceso.

3. Los procesos con una relación de sangre pueden usar canalizaciones para la comunicación de procesos, como procesos abuelos, procesos padre-hijo y procesos hermanos. Esto se debe a que todos tienen un ancestro común. Siempre que el ancestro común llame a pipe para crear una canalización. , sus descendientes pueden comunicarse entre sí.

4. No existe una fuerte correlación entre los tiempos de lectura y escritura de las dos partes en la comunicación de canalización (flujo de bytes), es decir, no se afectan entre sí. Por ejemplo, el proceso secundario anterior puede leer con tanta frecuencia como quiere, y no está limitado por la otra parte de la tubería.

5. Tener cierta capacidad de coordinación, de modo que tanto el extremo de lectura como el extremo de escritura puedan comunicarse de acuerdo con ciertas reglas, con su propio mecanismo de sincronización (reglas de lectura y escritura)

Resumir

Lo anterior es todo el contenido de este artículo, si ha recibido algo, espero prestarle atención tres veces.

Supongo que te gusta

Origin blog.csdn.net/zcxmjw/article/details/131367115
Recomendado
Clasificación