我的问题就像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)