为啥我的 (ubuntu 11.10 bash 4.2.10, x86_64 ) 命名管道会堵塞?

Posted

技术标签:

【中文标题】为啥我的 (ubuntu 11.10 bash 4.2.10, x86_64 ) 命名管道会堵塞?【英文标题】:why does my (ubuntu 11.10 bash 4.2.10, x86_64 ) named pipe get clogged?为什么我的 (ubuntu 11.10 bash 4.2.10, x86_64 ) 命名管道会堵塞? 【发布时间】:2012-02-08 18:50:23 【问题描述】:

第 1 步:我打开一个终端并输入

mkfifo mypipe
cat < mypipe

第 2 步:我打开另一个并输入:

for elem in 1..100 ; do echo "$elem" > mypipe ; done

打印出随机数量的数字,第一个脚本退出第二个脚本挂起。 请分享智慧。 Ubuntu的错误?如果需要更多信息,请询问,我认为没有任何相关的 atm。

谢谢, 你们太棒了。

【问题讨论】:

【参考方案1】:

命名管道的工作方式是,当写入进程关闭管道时,读取进程会收到一个 EOF。当cat 看到文件已结束时,它会停止读取并退出。这里 bash 似乎在循环中大部分时间都在重用打开的文件,而不是在每次运行时关闭并重新打开它。

为了确保文件在你可以这样写的时候打开和关闭:

(for elem in 1..100 ; do echo "$elem"  ; done) > mypipe

要让cat 在每次运行中只输出一个数字,您必须使用程序/bin/echo 而不是内置的echo。这会强制 Bash 在每次循环运行时打开和关闭文件:

for elem in 1..100 ; do /bin/echo "$elem" > mypipe ; done

【讨论】:

【参考方案2】:

如果有错误,那就是cat 面打印了多个。这是一个竞赛条件。发生的事情是cat 正在读取一行,然后才能读取 EOF(因为它们是单独的写入)echo 写入下一行,所以cat 得到了,等等。最终,它似乎,catecho 重定向可以写入管道之前到达 EOF。如果您想一次将所有数字写入管道,请将重定向移至末尾:

for elem in 1..100 ; do echo "$elem" done > mypipe 

或者更好,

seq 100 > mypipe

如果您希望cat 一次只能获得一个...我不太确定您如何轻松做到这一点(尽管我相信如果有必要我可以破解它)。

【讨论】:

以上是关于为啥我的 (ubuntu 11.10 bash 4.2.10, x86_64 ) 命名管道会堵塞?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Ubuntu 11.10 下安装KScope

如何在32位ubuntu11.10 下编译android 4.0.1源码和goldfish内核

在 Ubuntu 11.10 上启用 cURL 时遇到问题

关于Ubuntu 11.10开机启动项

ubuntu 11.10 安装apache2 tomcat6

如何:在 Ubuntu 11.10 上安装 Imagick(用于 php)