Posso canalizar dois processos para o outro?

8

Em esta página de O design e a implementação do Sistema Operacional 4.4BSD , diz-se que:

A major difference between pipes and sockets is that pipes require a common parent process to set up the communications channel

No entanto, se eu gravar corretamente, a única maneira de criar um novo processo é fork um existente. Por isso, não consigo ver como dois processos não puderam ter um ancestral comum. Tenho então razão em pensar que qualquer par de processos pode ser canalizado entre si?

    
por qdii 12.05.2013 / 14:04

3 respostas

7

Am I then right to think that any pair of processes can be piped to each other?

Não realmente.

Os canais precisam ser configurados pelo processo pai antes de o filho ou os filhos serem bifurcados. Uma vez que o processo filho é bifurcado, seus descritores de arquivo não podem ser manipulados "de fora" (ignorando coisas como depuradores), o pai (ou qualquer outro processo) não pode fazer a parte "configurar as comunicações. Canal" após o fato .

Então, se você tomar dois processos aleatórios que já estão em execução, não será possível configurar um canal entre eles diretamente. Você precisa usar algum tipo de soquete (ou outro mecanismo IPC) para fazer com que eles se comuniquem. (Mas note que alguns sistemas operacionais, como o FreeBSD entre eles, permitem que você envie descritores de arquivos em soquetes do domínio Unix.)

    
por 12.05.2013 / 14:41
4

Essa frase não é muito clara. Primeiro, pai deve ser ancestral , pois o processo de configuração do canal pode ser pai / mãe, avô ou avô-grand-grand… ou um dos os processos de comunicação. Segundo, a sentença não significa “se você quer um pipe, deve existir um processo ancestral comum”, mas “se você quer um pipe, um processo ancestral comum deve configurá-lo”.

Sob o capô, um processo estabelece um tubo consigo mesmo. O pipe é um descritor de arquivo como qualquer outro, ou mais precisamente um par de descritores de arquivos, um para cada extremidade. O processo que criou o pipe pode usá-lo imediatamente para enviar dados para si mesmo, embora isso raramente seja útil (embora um autopreenchimento tem seu uso).

Um idioma típico é para um processo configurar um canal, depois separar um processo filho e fechar uma extremidade do canal no pai e a outra extremidade do canal no filho. Isso permite que o pai e o processo filho se comuniquem em uma direção. Se os processos precisam de comunicação bidirecional, eles precisam de dois tubos (exceto em algumas variantes unix onde os tubos são bidirecionais).

Os pipes são herdados por qualquer criança, então o processo que criou o pipe pode não estar envolvido na comunicação. Por exemplo, um pipe em um shell criado entre dois comandos externos, como ls | rot13 , envolve as seguintes etapas:

  • O shell cria um pipe.
  • O shell bifurca um processo. O filho fecha a extremidade de leitura do canal e chama execve on ls .
  • O shell bifurca um processo. O filho fecha a extremidade de gravação do pipe e chama execve on rot13 .
  • O shell fecha ambas as extremidades do pipe e aguarda a saída de ambos os subprocessos.

Se dois processos existentes quiserem se comunicar, eles podem usar um canal nomeado . (Bem, também há descritor de arquivo passando , mas não é para os desmaiados coração.)

    
por 13.05.2013 / 02:52
2

O shell do pipeline é o pai comum que configura um canal de comunicação entre os vários membros do pipeline.

Qualquer processo pode ser canalizado para qualquer outro. Os únicos processos que podem ser utilmente serem canalizados são os "filtros" que lêem de stdin e escrevem para stdout.

Por exemplo, se você emitir o comando

$ tail -f /etc/motd | tail -f | cat > /dev/null

ps -eaH mostrará que o gato e suas duas caudas são filhos da casca que invoca:

 1675 pts/0    00:00:00     bash
 2483 pts/0    00:00:00       tail
 2484 pts/0    00:00:00       tail
 2485 pts/0    00:00:00       cat
    
por 12.05.2013 / 14:35