Desenvolvimento remoto Linux - PIPE de pipe anônimo e FIFO de pipe nomeado

contente

1. O que é um pipeline

2. Pipeline Anônimo (PIPE)

1. Introdução ao pipeline anônimo

2, função de tubo ()

3. Os processos pai e filho se comunicam por meio de pipes anônimos

(1) Análise de demanda

(2) Implementação do código

(3) Resultados do teste

3. Tubos Nomeados (FIFO)

1. Introdução aos pipes nomeados

2. Crie um pipe nomeado

(1) Modo de linha de comando

(2) Método de código

(3) protótipo da função mkfifo()

3. Abra o arquivo de pipe nomeado FIFO

4. Regras abertas para pipes nomeados


1. O que é um pipeline

        Pipes são a forma mais antiga de comunicação entre processos no Unix. Chamamos um fluxo de dados conectado de um processo a outro de "pipe".

        Os tubos são half-duplex e os dados só podem fluir em uma direção. Quando duas partes precisam se comunicar, dois canais precisam ser estabelecidos. Ele só pode ser usado para comunicação entre processos pai e filho ou entre processos irmãos (processos com afinidade).

        Normalmente, um pipe é criado por um processo e, em seguida, o processo chama fork, após o qual o pipe pode ser usado entre os processos pai e filho. Ou seja, a criação do pipeline é realizada antes de fork().

2. Pipeline Anônimo (PIPE)

1. Introdução ao pipeline anônimo

        Um pipe anônimo também é um pipe anônimo. Um pipe pode ser criado através da função pipe(), e os pipes anônimos só podem se comunicar em processos relacionados. O que está relacionado? Como processo pai e processo filho ou dois processos filho criados pelo mesmo processo pai.

        Como o pipe anônimo é half-duplex, para realizar a comunicação entre dois processos, é necessário criar dois pipes, um com a direção pai->filho e outro com filho->pai.

2, função de tubo ()

        A função da função pipe() é criar um pipe sem nome.A seguir está o protótipo da função pipe().

#include <unistd.h> //Arquivo de cabeçalho

int pipe(int pipefd[2]);

parâmetro:

pipefd[2]: Array de descritores de arquivo, pipefd[0] representa o final da leitura e pipefd[1] representa o final da gravação.

valor de retorno:

Retorna 0 em caso de sucesso, -1 em caso de falha.

O código a seguir usa a função pipe() para testar a comunicação entre os processos pai e filho por meio de pipes anônimos.

3. Os processos pai e filho se comunicam por meio de pipes anônimos

(1) Análise de demanda

1. Dois pipelines precisam ser preparados, pai -> filho, filho -> pai.

2. Pai->filho pipeline, o pai quer enviar dados, então feche o final de leitura, e o filho quer receber dados, então feche o final de gravação.

3. Filho -> pipeline do pai, o pai quer receber dados, então feche o final de gravação, e o filho quer enviar dados, então feche o final de leitura.

4. Os processos pai e filho precisam ler ou enviar informações por meio do loop while.

(2) Implementação do código

#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

using namespace std;

int main()
{
	//pipe匿名管道:1、没有名字  2、是用在由同一个进程fork具有亲缘关系的子进程

	int pid = 0;
	int fatherTochild[2] = { 0 };//父到子文件描述符数组
	int childTofather[2] = { 0 };//子到父文件描述符数组
	
	//管道创建要在进程之前,管道一定是放在进程里面使用的,所以管道要在进程创建前创建
	if (pipe(fatherTochild) < 0 || pipe(childTofather) < 0)
	{
		perror("pipe open error");//管道创建失败
	}
	else
	{
		cout << "管道开启成功" << endl;
		pid = fork();
		//子进程
		if (pid == 0)
		{
			char resbuf[255] = { 0 };
			
			close(fatherTochild[1]);//子进程  父到子 关闭写端
			
			close(childTofather[0]);//子进程  子到父  关闭读端
			while (1)
			{
				read(fatherTochild[0], resbuf, sizeof(resbuf));//接收父亲发过来的信息
				if (strlen(resbuf) != 0)
				{
					cout << "父亲对儿子说:" << resbuf << endl;
				}
				bzero(resbuf, sizeof(resbuf));//清空数组

				cout << "儿子:";
				fgets(resbuf, sizeof(resbuf), stdin);//控制台输入
				write(childTofather[1], resbuf, sizeof(resbuf));//给父亲发信息
				bzero(resbuf, sizeof(resbuf));//清空数组
			}
		}
		else if (pid > 0)//父进程
		{
			char sendbuf[255] = { 0 };
			close(fatherTochild[0]);//父进程  父到子 关闭读端
			
			close(childTofather[1]);//父进程  子到父 关闭写端
			while (1)
			{
				cout << "父亲:";
				fgets(sendbuf, sizeof(sendbuf), stdin);//控制台输入
				write(fatherTochild[1], sendbuf, sizeof(sendbuf));//给孩子发信息
				bzero(sendbuf, sizeof(sendbuf));//清空数组

				read(childTofather[0], sendbuf, sizeof(sendbuf));//接收孩子发过来的信息
				if (strlen(sendbuf) != 0)
				{
					cout << "儿子对父亲说:" << sendbuf << endl;
				}
				bzero(sendbuf, sizeof(sendbuf));//清空数组
			}
		}
	}
	
	return 0;
}

(3) Resultados do teste

        Através dos resultados dos testes, pode-se constatar que o pai digitou as informações primeiro, pois o filho lê() primeiro, e a função read() é uma função de bloqueio, que termina quando a informação é lida. Depois que o filho recebe a informação, o filho executa read(), e então executa write(). Ao mesmo tempo, depois que o pai envia a informação, ele executa write(), e então executa read(), esperando o filho para enviar as informações. Desta forma, a informação é enviada e recebida ciclicamente, e a comunicação entre os processos pai e filho é realizada.

3. Tubos Nomeados (FIFO)

1. Introdução aos pipes nomeados

        Os pipes anônimos acima só podem alcançar a comunicação entre processos com parentesco, se quisermos trocar dados entre processos não relacionados, podemos usar arquivos FIFO para fazer o trabalho, que geralmente são chamados de pipes nomeados.

        Um pipe nomeado é um tipo especial de arquivo, existe na forma de um arquivo, mas não é um arquivo real e não retém dados, mas apenas desempenha um papel na transmissão de dados.

2. Crie um pipe nomeado

(1) Modo de linha de comando

mkfifo xxx.fifo

(2) Método de código

umask(0);
mkfifo("/root/projects/test.fifo", 0777);

(3) protótipo da função mkfifo()

Função: Criar arquivo de pipeline .fifo

#include <sys/types.h> //Arquivo de cabeçalho
#include <sys/stat.h> //Arquivo de cabeçalho

int mkfifo(const char *pathname, mode_t mode);

parâmetro:

nome do caminho: caminho do arquivo

modo: permissões de arquivo

valor de retorno:

Retorna 0 em caso de sucesso, -1 em caso de falha.

3. Abra o arquivo de pipe nomeado FIFO

1. FIFO é diferente do pipe criado pela chamada do pipe, é um arquivo com nome e representa um descritor de arquivo aberto.

2. Deve ser aberto antes de ler ou escrever nele.

3. O arquivo FIFO também deve ser aberto ou fechado com as funções de abrir e fechar, exceto por algumas funções adicionais, todo o processo de operação é o mesmo que a operação de arquivo.

4. O nome do caminho de um arquivo FIFO passado para a chamada aberta não é o nome do caminho de um arquivo normal.

4. Regras abertas para pipes nomeados

1. Se a operação de abertura atual for abrir o FIFO para leitura, se um processo correspondente já tiver aberto o FIFO para escrita, a operação de abertura atual retornará com sucesso; caso contrário, poderá bloquear até que um processo correspondente abra o FIFO para escrita ( atualmente A operação de abertura ativa o sinalizador de bloqueio, ou seja, apenas O_RDONLY é definido, ao contrário, se a operação de abertura atual não definir o sinalizador de não bloqueio, ou seja, O_NONBLOCK, ela retornará sucesso.

2. Se a operação de abertura atual for abrir o FIFO para escrita, se um processo correspondente já tiver aberto o FIFO para leitura, a operação de abertura atual retornará com sucesso; caso contrário, poderá bloquear até que um processo correspondente abra o FIFO para leitura ( atualmente O sinalizador de bloqueio está definido para a operação de abertura); ou um erro ENXIO é retornado (o sinalizador de bloqueio não está definido para a operação de abertura atual).

3. Em termos leigos, para abrir um arquivo pipe nomeado FIFO, um processo precisa abri-lo para escrita e outro processo precisa abri-lo para leitura. Somente quando há leitura aberta e escrita aberta, o pipe nomeado pode ser aberto com sucesso . Assim como um cano de água, a entrada e a saída do cano de água precisam estar abertas ao mesmo tempo para que a água flua.

A originalidade não é fácil, por favor indique a fonte ao reimprimir.

Se for útil para você, você pode curtir, coletar + seguir, e será atualizado continuamente (hee hee).

Acho que você gosta

Origin blog.csdn.net/wmcy123/article/details/123606929
Recomendado
Clasificación