Eu tenho dois programas simples: A
e B
. A
executaria primeiro, depois obteria B
o “stdout” A
e o usaria como seu “stdin”. Suponha que eu esteja usando um sistema operacional GNU/Linux e a maneira mais simples possível de fazer isso seria:
./A | ./B
Se eu tivesse que descrever esse comando, eu diria que é um comando que recebe entrada (ou seja, lê) de um produtor ( A
) e grava em um consumidor ( B
). Essa é uma descrição correta? Estou faltando alguma coisa?
A única coisa sobre sua pergunta que se destaca como errada é que você diz
Na verdade, ambos os programas seriam iniciados praticamente ao mesmo tempo. Se não houver entrada para
B
quando tentar ler, ele bloqueará até que haja entrada para ler. Da mesma forma, se não houver ninguém lendo a saída deA
, suas gravações serão bloqueadas até que sua saída seja lida (algumas delas serão armazenadas em buffer pelo pipe).A única coisa que sincroniza os processos que fazem parte de um pipeline é o I/O, ou seja, a leitura e escrita no pipe. Se nenhuma escrita ou leitura acontecer, os dois processos serão executados totalmente independentes um do outro. Se um ignorar a leitura ou escrita do outro, o processo ignorado será bloqueado e eventualmente será morto por um
SIGPIPE
sinal (se estiver escrevendo) ou obterá uma condição de fim de arquivo em seu fluxo de entrada padrão (se estiver lendo) quando o outro processo terminar .A maneira idiomática de descrever
A | B
é que é um pipeline contendo dois programas. A saída produzida na saída padrão do primeiro programa está disponível para ser lida na entrada padrão pelo segundo ("[a saída de]A
é canalizada para [a entrada de]B
"). O shell faz o encanamento necessário para permitir que isso aconteça.Se você quiser usar as palavras "consumidor" e "produtor", suponho que tudo bem também.
O fato de serem programas escritos em C não é relevante. O fato de ser Linux, macOS, OpenBSD ou AIX não é relevante.
O termo geralmente usado na documentação é "pipeline" , que consiste em um ou mais comandos, veja a definição POSIX Então, tecnicamente falando, são dois comandos que você tem lá, dois subprocessos para o shell (ou
fork()+exec()
comandos externos 'ed ou subshells )Quanto à parte produtor-consumidor , o pipeline pode ser descrito por esse padrão, pois:
/proc/<pid>/fd
diretório).stdout
e os consumidores leemstdin
como se fossem um único comando sendo executado, ou seja, eles podem existir um sem o outro .A diferença que vejo aqui é que, diferentemente do Produtor-Consumidor em outras linguagens, os comandos do shell usam buffer e gravam stdout quando o buffer é preenchido, mas não há menção de que o Produtor-Consumidor deve seguir essa regra - apenas espere quando a fila estiver cheia ou descarte data (que é outra coisa que o pipeline não faz).