Por que a entrada canalizada está bem para o zenity, mas o arquivo não funciona?

3

Minha pergunta é tão simples quanto o que o zenity --text args diz no exemplo ... mas o que está causando 100% de ocupação do CPU pelo redirecionamento?
... (e, a propósito, esse uso específico de < na verdade é chamado de redirection . Parece que está criando uma direção, em vez de re -direcionar).

echo "Peacocks talking of the colour grey."> test
cat test | zenity --text='This does NOT hog the CPU'   --list --column='#' --width=450 
<test      zenity --text='This hogs 100% of CPU usage' --list --column='#' --width=450
 

Estou muito feliz em usar cat test | (porque não é inútil nesse caso; funciona e < e | são de alguma forma diferentes, mas não consegui rastreá-lo novamente. ..

Para ser claro: <test e cat test | funcionam. A caixa de diálogo zenity aparece e é totalmente funcional em ambos os casos, mas enquanto a versão <test da caixa de diálogo for mantida aberta, ela usa 100% da CPU (de um núcleo) ... 94% no único "core" VMs ...

    
por Peter.O 16.07.2011 / 02:27

2 respostas

5

Parece um erro no zenity. Você pode ver o que está acontecendo usando a ferramenta strace (eu agrupei as linhas de strace neste post para facilitar a leitura).

Com a versão do pipe, esta linha no strace mostra o que acontece quando o pipe é fechado (porque cat sai):

poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}, {fd=0, events=POLLIN}], \
     3, 0) = 1 ([{fd=0, revents=POLLIN|POLLHUP}])

Essa parte no final - fd=0, revents=POLLIN|POLLHUP , em particular POLLHUP - diz a zenity que stdin desligou (o gravador do pipe foi embora). O Zenity está processando isso corretamente e fechando o fd 0 depois.

Os arquivos não recebem POLLHUP events - em vez disso, um resultado read(2) de zero significa EOF. Este é um caminho de código diferente para o zenity. Pesquise novamente por fd 0 e é isso que acontece:

poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}, {fd=0, events=POLLIN}],\
     3, 0) = 1 ([{fd=0, revents=POLLIN}])
read(0, "", 1024)       = 0

Esse deve ser o fim dele - a leitura zero deve fazer com que o zenity feche o fd 0. Mas isso não acontece. A saída de strace acima continua repetindo, pois o zenity mantém o polling fd 0. Até que fd 0 seja fechado, ele estará sempre pronto para leitura, pois é assim que os descritores de arquivo no EOF funcionam, já que você precisa lê-lo para obter o resultado EOF.

Como o zenity não está respondendo corretamente a EOF em stdin, ele continua em loop em um loop poll(2) / read(2) , onde poll retorna imediatamente, assim como read . Mais uma vez, e de novo e de novo ...

    
por 16.07.2011 / 13:47
0

Tente isto:

zenity --text='This does NOT hog the CPU' --list --column='#' --width=450 <(cat test)
    
por 16.07.2011 / 03:31