Por que usar um pipe nomeado em vez de um arquivo?

29

Li recentemente sobre pipes nomeados e não consegui entender por que eles existem.
Eu li em algum lugar que usar um pipe nomeado é menos demorado do que usar um arquivo.

Por que isso é assim?
Os pipes nomeados também devem ser armazenados na memória (e talvez trocados, assim como arquivos). Tanto quanto eu posso ver, eles devem obter um inode que deve ser referenciado pelo diretório atual, assim como os arquivos. Além disso, eles devem ser removidos pelo programador, assim como os arquivos.

Então, onde está a vantagem?

    
por user3122885 17.04.2014 / 18:56

4 respostas

26

Quase tudo no Linux pode ser considerado um arquivo , mas a principal diferença entre um arquivo regular e um named pipe é que um arquivo nomeado pipe é uma instância especial de um arquivo que não possui conteúdo no sistema de arquivos.

Aqui está uma citação de man fifo :

  

Um arquivo especial FIFO (um pipe nomeado) é semelhante a um pipe, exceto que é acessado como parte do sistema de arquivos. Pode ser aberto por múltiplos processos para leitura ou escrita. Quando os processos estão trocando dados através do FIFO, o kernel passa todos os dados internamente sem gravá-los no sistema de arquivos. Assim, o arquivo especial FIFO não tem conteúdo no sistema de arquivos; a entrada do sistema de arquivos serve apenas como um ponto de referência para que os processos possam acessar o pipe usando um nome no sistema de arquivos.

     

O kernel mantém exatamente um objeto pipe para cada arquivo especial FIFO que é aberto por pelo menos um processo. O FIFO deve ser aberto em ambas as extremidades (leitura e escrita) antes que os dados possam ser passados. Normalmente, abrir os blocos FIFO até que a outra extremidade seja aberta também.

Então, na verdade, um pipe nomeado não faz nada até que algum processo leia e grave nele. Ele não ocupa nenhum espaço no disco rígido (exceto um pouco de meta-informação), ele não usa a CPU.

Você pode verificar isso fazendo isso:

Crie um canal nomeado

$ mkfifo /tmp/testpipe

Vá para algum diretório, por exemplo /home/user/Documents , e gzip tudo dentro dele, usando o pipe nomeado.

$ cd /home/user/Documents
$ tar cvf - . | gzip > /tmp/testpipe &
[1] 28584

Aqui você deve ver o PID do processo gzip. Em nosso exemplo, foi 28584.

Agora, verifique o que este PID está fazendo

$ ps u -P 28584
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
c0rp     28584  0.0  0.0  29276  7800 pts/8    S    00:08   0:00 bash

Você verá que está usando sem recursos . 0% de uso da CPU, 0% de uso de memória.

Verifique o palpite sobre o uso do espaço no arquivo

$ du -h /tmp/testpipe
0   testpipe

E novamente 0 , nada. O tubo de ensaio pode ser usado novamente, se necessário.

Não esqueça de matar o gzip, usando kill -15 28584 . E remova nosso pipe nomeado usando rm /tmp/testpipe

Exemplo de uso

Você pode redirecionar quase tudo usando o pipe nomeado. Como exemplo, você pode ver este um proxy de linha .

Também aqui está mais uma explicação legal sobre o uso do pipe nomeado. Você pode configurar dois processos em um servidor para se comunicar usando um canal nomeado em vez de pilha TCP / IP. É muito mais rápido e não carrega recursos de rede. Por exemplo, seu servidor da Web pode se comunicar com o banco de dados diretamente usando um canal nomeado, em vez de usar localhost address ou escutar alguma porta.

    
por c0rp 17.04.2014 / 21:13
11

É verdade que você não usará memória do sistema, mas o fato de não usar cpu em seu exemplo é apenas porque você não leu o pipe, então o processo está aguardando.

Considere o seguinte exemplo:

mkfifo /tmp/testpipe
tar cvf - / | gzip > /tmp/testpipe

Agora, abra um novo console e execute:

watch -n 1 'ps u -P $(pidof tar)

E em um terceiro console:

cat /tmp/testpipe > /dev/null

Se você olhar para o relógio cmd (2º termo), ele mostrará um aumento no consumo de CPU!

    
por GARCIN David 21.08.2014 / 19:06
0

Você pode deixar um programa parado e ouvir um pipe nomeado para algum evento externo. Assim que o evento externo ocorrer (por exemplo, chegada de novos dados) isso pode ser detectado por algum outro programa que, por sua vez, abre o canal para gravação, gravando os dados relevantes do evento no pipe. Quando a instrução close é emitida, o programa de escuta receberá o fluxo de dados através do pipe por meio de uma instrução read e está pronto para processar o que obteve. Não se esqueça de fechar o tubo depois de ler o conteúdo. O programa de escuta também pode retornar resultados de seu processamento através do mesmo, ou através de outro pipe nomeado. Essas comunicações entre programas são muito conveniente às vezes.

    
por Per Anton Ronning 01.11.2016 / 10:17
0

Aqui está um caso de uso em que os pipes nomeados podem poupar muito tempo removendo a E / S.

Vamos supor que você tenha um BigFile, por exemplo, 10G.

Você também tem divisões deste BigFile em pedaços de 1G, BigFileSplit_01 para BigFile_Split_10.

Agora você tem uma dúvida sobre a correção do BigFileSplit_05

Ingenuamente, sem pipes nomeados, você criaria uma nova divisão do BigFile e compararia:

dd if=BigFile of=BigFileSplitOrig_05 bs=1G skip=4 count=1
diff -s BigFileSplitOrig_05 BigFileSplit_05
rm BigFileSplitOrig_05

Com pipes nomeados você faria

mkfifo BigFileSplitOrig_05
dd if=BigFile of=BigFileSplitOrig_05 bs=1G skip=4 count=1 &
diff -s BigFileSplitOrig_05 BigFileSplit_05
rm BigFileSplitOrig_05

Isso pode não parecer à primeira vista uma grande diferença ... mas com o tempo a diferença é enorme!

Opção 1:

  • dd: leia 1G / gravação 1G (1)
  • diff: leia 2G
  • rm: clusters alocados gratuitos / remover entrada de diretório

Opção 2:

  • dd: nada! (vai para o pipe nomeado)
  • diff: leia 2G
  • rm: nenhum cluster alocado para gerenciar (na verdade, não escrevemos nada no sistema de arquivos) / remove a entrada de diretório

Então, basicamente, o pipe nomeado salva aqui uma leitura e gravação de 1G mais alguma limpeza do sistema de arquivos (já que não escrevemos nada para o sistema de arquivos, mas para o nó fifo vazio).

Não fazer I / O, especialmente escreve, também é bom para evitar o desgaste de seus discos. É ainda mais interessante quando você trabalha com SSDs, pois eles têm um número limitado de gravações antes que as células morram.

(1) Obviamente, outra opção seria criar esse arquivo temporário na RAM, por exemplo, se / tmp estiver montado na RAM (tmpfs). No entanto, você seria limitado pelo tamanho do disco de RAM, enquanto o "truque de pipe nomeado" não tem limites.

    
por Zakhar 06.08.2017 / 11:54

Tags