Como um shell canalizado equilibra suas taxas de saída / entrada? [duplicado]

11

Eu venho de experiência em programação web, e me vejo interessado em uma peculiaridade de usar um shell local. Eu entendo que quando um programa lê um arquivo, ele pode ler a qualquer taxa que seja necessária. Mas estou curioso para saber, como funciona quando um programa recebe entrada de outro programa e não pode processá-lo em tempo real?

Um bom exemplo seria a codificação de vídeo. Suponha que eu aponte um decodificador para o arquivo de vídeo, então a saída é canalizada como entrada do codificador. O tamanho total do vídeo decodificado é maior do que o de ram + swap, então eu acho que não há como armazená-lo completamente. Eu encontrei sobre ler e escrever chamadas para stdin e stdout, mas estou interessado em saber o que realmente acontece quando o codificador deste exemplo não consegue lidar com todos os dados de uma só vez. De alguma forma, informa o decodificador sobre a taxa desejada? O programa decodificador precisa ser especificamente preparado para esse sinal e modificar sua velocidade de processamento de acordo? Se não, como tudo fica equilibrado no final?

    
por Red 29.10.2012 / 11:57

2 respostas

5

Quando um gravador grava em um pipe e o pipe está cheio (seu tamanho é limitado a alguns kilobytes), seu processo bloqueia até que um dos leitores libere algum espaço. Da mesma forma, quando um leitor lê de um pipe, seu processo bloqueia até que haja algo lá.

Há também gravações e leituras assíncronas que um programador pode usar para enfileirar essas leituras e gravações.

Eu sugiro que leia Gudes de Beej , começando com Beej's Guia para a comunicação entre processos Unix

Você o chama com dois argumentos, o primeiro é um tempo de sono para o escritor, o segundo é um tempo de sono para o leitor. Tente chamá-lo com args 0 3 e 3 0

#!/bin/sh
write_sleep=$1
read_sleep=$2
writer(){
  echo writing output >&2
  echo hi
  sleep $write_sleep
  echo writing output >&2
  echo hi
  sleep $write_sleep
  echo writing output >&2
  echo hi
  sleep $write_sleep
}
reader(){
  while true; do
    echo getting input >&2
    read input
    [ $input ] || { echo input is empty >&2 &&  break; }
    echo $input
    sleep $read_sleep
  done
}

writer | reader
    
por 29.10.2012 / 12:07
4

Pipes são descritores unix usuais no nível programático. Quando você configura dois programas para se comunicar através de um pipe, tudo o que eles vêem primeiro é a saída padrão e os descritores de entrada padrão, com os quais eles interagem, porque o shell os configurou dessa maneira. Existem algumas peculiaridades com estes descritores quando configurados desta forma, mas os processos interagem com eles como com qualquer outro descritor de arquivos (é toda a filosofia unix, você sabe).

Basicamente, o processo escritor pode escrever o quanto ele quiser no pipe, mas, como o pipe tem um limite máximo de armazenamento (um buffer), ele pode ser bloqueado se o pipe estiver cheio ou a solicitação puder ser atendida. como "tente novamente mais tarde" se o escritor não quisesse bloquear.

Por outro lado, o leitor pode ler o quanto quiser, mas também pode ser bloqueado (ou respondido com "tente novamente mais tarde" também) se o tubo estiver vazio.

    
por 29.10.2012 / 18:04