Ruby 从标准输出流式传输数据

Ruby 从标准输出流式传输数据,ruby,Ruby,因此,我有以下代码: reader.rb threader.rb 一个ruby脚本是一个很简单的微调器,它每秒钟都会放入标准输出 另一个是运行该脚本,我想在数据进入时捕获它。因此,我希望流以非阻塞方式从标准输出读取 我好像没法让它工作。我想我正在正确设置fctnlO_NONBLOCK标志,但可能我没有正确设置。您的代码工作正常。您只缺少一块,那就是刷新线程器的输出缓冲区 问题是STDOUT几乎总是被缓冲的,在这种情况下,除非明确告诉它,否则直到线程程序退出后才会刷新缓冲区 这就是为什么读者看不到

因此,我有以下代码:

reader.rb threader.rb 一个ruby脚本是一个很简单的微调器,它每秒钟都会放入标准输出

另一个是运行该脚本,我想在数据进入时捕获它。因此,我希望流以非阻塞方式从标准输出读取


我好像没法让它工作。我想我正在正确设置fctnl
O_NONBLOCK
标志,但可能我没有正确设置。

您的代码工作正常。您只缺少一块,那就是刷新
线程器的输出缓冲区

问题是STDOUT几乎总是被缓冲的,在这种情况下,除非明确告诉它,否则直到线程程序退出后才会刷新缓冲区

这就是为什么读者看不到任何东西,然后当threader退出并且STDOUT被刷新时,它会突然获得突发输出

因此,此测试的简单修复方法是:

10.times do
  $stdout.puts "test"
  $stdout.flush
  sleep 1
end
但是请注意,由于您使用非块读取,因此读卡器将忙循环(!)并消耗100%的CPU。要防止busyloping,您真正应该做的是在读取之前等待传入的数据

这可以通过以下方式实现:

。。。
环道

IO.select([stdout])#请直接在此处发布代码,而不是链接到它,这样可以防止将来链接不再存在时问题变得无用。
10.times do
  $stdout.puts "test"
  sleep 1
end
10.times do
  $stdout.puts "test"
  $stdout.flush
  sleep 1
end
...
loop do
  IO.select([stdout]) # <- waits for data (any data, even 1 byte)
  data = stdout.read_nonblock(8)
  print data
end  
...