所以我有以下代码:
reader.rb
require 'open4'
def streamer(stdout)
begin
loop do
data = stdout.read_nonblock(8)
print data
end
rescue Errno::EAGAIN
retry
rescue EOFError
puts 'End of file'
end
end
pid, stdin, stdout, stderr = Open4::popen4 "ruby threader.rb"
stdout.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
streamer(stdout)threader.rb
10.times do
$stdout.puts "test"
sleep 1
end一个ruby脚本是一个简单的旋转器,它每秒都会输出到stdout。
另一个是用来运行该脚本的,我想捕获传入的数据。所以我想让流以非阻塞方式从stdout读取。
我似乎不能让它工作。我认为我正确地设置了fctnl O_NONBLOCK标志,但也许我没有。
发布于 2012-05-02 15:41:19
您的代码运行良好。您只遗漏了一件事,那就是刷新threader的输出缓冲区。
问题是STDOUT几乎总是被缓冲的,在这种情况下,除非被明确告知,否则不会刷新缓冲区,直到线程退出之后。
这就是为什么阅读器什么都看不到,然后当线程退出并且STDOUT被刷新时,它会突然得到一系列输出。
因此,这个测试的简单修复方法是:
10.times do
$stdout.puts "test"
$stdout.flush
sleep 1
end但是请注意,因为您正在使用NONBLOCK阅读,所以您的读者将忙于循环(!)消耗100% CPU。您真正应该做的是在读取之前等待传入的数据,以防止繁忙循环。
这可以使用IO.select来完成
...
loop do
IO.select([stdout]) # <- waits for data (any data, even 1 byte)
data = stdout.read_nonblock(8)
print data
end
...https://stackoverflow.com/questions/10409140
复制相似问题