为什么管道输入对 zenity 没问题,但是

为什么管道输入对 zenity 没问题,但是

我的问题就像zenity --text示例中的参数所说的一样简单......但是是什么导致重定向导致 100% CPU 占用?
...(顺便说一句,这种特殊用法<实际上称为redirection。看起来它是在创建一个方向,而不是关于- 导演)..

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
 

我很高兴使用cat test |(因为在这种情况下它并不是无用的;它可以工作并且<并且|在某种程度上有所不同,但我无法再次追踪它......

需要明确的是:<test两者cat test |都有效。在这两种情况下,zenity 对话框都会出现并且功能齐全,但只要<test该对话框的版本保持打开状态,它就会使用 100% CPU(一个核心)...在单“核心”VM 上为 94%。 。

答案1

这看起来像是 zenity 中的一个错误。您可以使用该工具查看发生了什么strace(我已将这篇文章中的 strace 行换行,以使其更易于阅读)。

对于管道版本,strace 中的这一行显示了当管道关闭(因为cat退出)时会发生什么:

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

最后的那部分 -fd=0, revents=POLLIN|POLLHUP特别是POLLHUP- 告诉 zenity 标准输入已经挂断(管道的编写者已经消失)。 Zenity 正在正确处理此问题并稍后关闭 fd 0。

文件不会获取POLLHUP事件 - 相反,read(2)结果为零意味着 EOF。这是 zenity 的不同代码路径。它再次轮询 fd 0,得到的结果如下:

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

这应该是它的结束 - 零读取应该导致 zenity 关闭 fd 0。但事实并非如此。上面的 strace 输出不断重复,因为 zenity 不断轮询 fd 0。在 fd 0 关闭之前,它将始终准备好读取,因为这就是 EOF 处的文件描述符的工作方式,因为您需要读取它才能获取 EOF 结果。

因为 zenity 没有正确响应 stdin 上的 EOF,所以它一直在poll(2)/read(2)循环上循环,其中poll立即返回,就像 一样read。一次又一次,一次又一次……

答案2

尝试这个:

zenity --text='This does NOT hog the CPU' --list --column='#' --width=450 <(cat test)

相关内容