UNIX Pipes
Para entendermos UNIX pipes, devemos primeiro recapitular o seguinte exemplo:
O programa
echo
redireciona a o output para o arquivorawcontent.txt
O conteúdo do arquivo é enviado como input para o comando
base64
Note o padrão aqui: temos uma pipeline de transformação de dados, onde o output de um programa é utilizado como input para o próximo programa.
Esta técnica de pipeline é utilizada em sistemas UNIX-like com o operador pipe |
.
UNIX pipelines
Ao invés de escrevemos nossa pipeline em múltiplas linhas, dificultando a legibilidade caso a complexidade aumente, podemos utilizar o operador |
para montar uma sentença única de comandos encadeados:
Muito melhor, não? E muito provável você já viu isto em algum lugar, por exemplo:
O output do comando ps
é enviado como input para o comando grep
. Cool, uh? Este pipe é chamado de pipe anônimo, ou anonymous pipe!
Anonymous pipe
Este pipe é chamado de anônimo justamente por não ter nome e ser temporário, pois o fd é criado durante a pipeline e depois é liberado.
Este tipo de IPC utiliza uma comunicação tem as seguintes caracterÃsticas:
One-way, ou seja, a informação trafega apenas e uma única direção
FIFO (first-in, first-out), ou seja, o output é redirecionado para um pipe e enfileirado como input em outro pipe do próximo comando
Quando um |
é criado, abre-se um par de file descriptors, uma para escrita e outro para leitura, tal como fizemos na seção anterior com custom fd.
Como a pipe é anônima, ambos file descriptors abertos são utilizados apenas no contexto da pipeline e são automaticamente liberados/fechados quando a pipeline termina.
Apesar de pipes anônimas |
serem utilizadas praticamente em quase tudo, é possÃvel criamos pipes com nomes?
Named pipes
Como o próprio nome diz, named pipes são pipes com nomes. São similares a pipes anônimas; empregam FIFO e são uma forma de IPC de via única (one-way).
A única diferença é que um named pipe é criado de forma explÃcita via comando mkfifo
, onde um arquivo é criado no filesystem e aberto para escrita e leitura.
Um arquivo chamado myqueue
é criado.
Vamos enviar uma mensagem para o pipe com o comando echo
, utilizando redirecionamento de stream >
que vimos na última seção:
Note que o processo fica bloqueado, Ã espera de algo.
IPC one-way
Por ser uma estrutura de fila FIFO simples e ser utilizado como one-way IPC, o sistema operacional precisa garantir que a mensagem será recebida por outro processo. Por isso o processo escritor, ou writer, fica bloqueado, pois é preciso que outro processo outro processo leitor (reader) para "consumir" a mensagem do pipe.
Em outra sessão do bash, vamos consumir a informação do pipe utilizando o comando cat
:
Yay!
O mesmo acontece se iniciarmos com o leitor: este fica bloqueado à espera que alguma mensagem chegue no pipe, no caso através de outro processo escritor.
Implementando um simples Background Job com UNIX pipes
Utilizando anonymous pipes e named pipes, podemos explorar a funcionalidade primitiva de um sistema de processamento assÃncrono (background job).
Começamos por definir os componentes:
Um processo leitor, ou consumer, fica infinitamente à espera de mensagens no pipe (fila)
Diferentes escritores, ou publishers, colocam mensagens no pipe de forma assÃncrona
O processo leitor (consumer) recebe cada mensagem no pipe e faz o devido processamento da mensagem
Consumer
Primeiro, criamos o pipe que representará a "fila" do nosso background job:
Agora, o consumer fica em loop infinito à espera de mensagens na fila.
Dentro do loop, consome a mensagem, decodifica-a e então mostra no screen:
E o consumer está pronto. Código final do arquivo consumer.sh
:
Em uma sessão do bash:
E em outra sessão do bash, podemos utilizar vários producers para enviar diversas mensagens codificadas para a fila:
Consultando o output na sessão do consumer:
Resumo
Que jornada! Nesta seção vimos a utilização de UNIX pipes para IPC, vimos a semelhança e diferença entre anonymous pipes |
e named pipes, bem como a implementação de um sistema de background jobs com pipes.
Agora, é hora de explorar uma forma ainda mais sofisticada de IPC: UNIX Sockets.
Last updated