加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 来自STDOUT的流数据

发布时间:2020-12-17 03:21:45 所属栏目:百科 来源:网络整理
导读:所以我有以下代码: 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' endendpid,stdin,stdout,stderr = Open4::popen4 "ruby
所以我有以下代码:

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脚本很简单,一个spinner每秒都会输入stdout.

另一个是运行该脚本,我想捕获数据.所以我希望流从stdout读取非阻塞.

我似乎无法让这个工作.我想我正在设置fctnl O_NONBLOCK标志,但也许我不是.

解决方法

你的代码工作正常.你只缺少一个,它正在刷新你的穿线器的输出缓冲区.

问题是STDOUT几乎总是被缓冲,在这种情况下,除非明确告知,否则缓冲区不会被刷新,直到threader退出.

这就是为什么读者不会看到任何东西,然后突然它会在穿线器退出并且STDOUT被冲洗时获得一阵输出.

所以这个测试的简单修复是:

10.times do
? $stdout.puts "test"
  $stdout.flush
? sleep 1
end

但请注意,因为您正在使用NONBLOCK阅读,您的阅读器将忙于循环(!)消耗100%的CPU.你应该做些什么来防止busylooping是在读取之前等待传入的数据.

这可以用IO.select完成:

...
loop do
  IO.select([stdout]) # <- waits for data (any data,even 1 byte)
  data = stdout.read_nonblock(8)
  print data
end  
...

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读