Eu tenho dois programas simples: A
e B
. A
funcionaria primeiro, depois B
pegaria o "stdout" de A
e o usaria como seu "stdin". Suponha que eu estou 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, diria que é um comando que recebe a entrada (isto é, lê) de um produtor ( A
) e grava em um consumidor ( B
). Essa é uma descrição correta? Estou faltando alguma coisa?
pipe
terminology
nihulus
fonte
fonte
Respostas:
A única coisa sobre sua pergunta que se destaca como errada é que você diz
De fato, ambos os programas seriam iniciados praticamente ao mesmo tempo. Se não houver entrada para
B
quando tentar ler, ele será bloqueado até que haja entrada para leitura. Da mesma forma, se não houver ninguém lendo a saídaA
, suas gravações serão bloqueadas até que a saída seja lida (algumas delas serão armazenadas em buffer pelo canal).A única coisa que sincroniza os processos que participam de um pipeline é a E / S, ou seja, a leitura e gravação no canal. Se nenhuma gravação ou leitura acontecer, os dois processos serão executados totalmente independentes um do outro. Se um ignorar a leitura ou gravação do outro, o processo ignorado bloqueará e, eventualmente, será morto por um
SIGPIPE
sinal (se estiver gravando) 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
"). A concha 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.
fonte
mkfifo
para criar um pipe nomeado, iniciar B na leitura de segundo plano do pipe e, em seguida, escrever A. Isso é muito difícil, pois o efeito seria o mesmo.yes | sed 10q
O termo geralmente usado na documentação é "pipeline", que consiste em um ou mais comandos, consulte definição de POSIX. Tecnicamente, são dois comandos que você tem lá, dois subprocessos para o shell (
fork()+exec()
comandos externos 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 Producer-Consumer em outros idiomas, os comandos do shell usam buffer e escrevem stdout quando o buffer é preenchido, mas não há menção de que o Producer-Consumer deva seguir essa regra - aguarde apenas quando a fila for preenchida ou descartada dados (que é outra coisa que o pipeline não faz).
fonte