In article <Pine.LNX.4.44.0402252137370.1397-100000 / fattire.ngdc.noaa.gov>, "Ara.T.Howard" <ahoward / fattire.ngdc.noaa.gov> writes: > i tried replacing with sysread but am now failing with > > sysread for buffered IO (IOError) You use eof? or other stdio related methods. Fortunately, you don't need such methods in this case. > io.nonblock{ io.read } > > but this does seem to work fine - i don't really know how to say 'read > everything that is available but do not block' from within a multi-threaded > application... You don't need nonblock because sysread doesn't block if some data are available. Note that IO.select blocks until some data are available. For example, your [ruby-talk:93618] can be modified as follows. require 'open3' STDOUT.sync = STDERR.sync = true command = <<'End' ruby -e " STDOUT.sync = true 10.times { STDOUT.puts Time.now; sleep 1 STDERR.puts Time.now; sleep 1 }" End i,o,e = Open3::popen3 command i.close inputs = [o, e] p inputs t = Thread.new do until inputs.empty? rios, = select inputs rios.each do |rio| p 'start...' begin text = rio.sysread(8192) rescue EOFError inputs.delete rio next end p [rio, text] p 'finish' end end end t.join Also, IO.select can be removed with two threads. require 'open3' STDOUT.sync = STDERR.sync = true command = <<'End' ruby -e " STDOUT.sync = true 10.times { STDOUT.puts Time.now; sleep 1 STDERR.puts Time.now; sleep 1 }" End i,o,e = Open3::popen3 command i.close t1 = Thread.new do loop { begin text = o.sysread(8192) rescue EOFError break end puts "STDOUT: #{text.inspect}" } end t2 = Thread.new do loop { begin text = e.sysread(8192) rescue EOFError break end puts "STDERR: #{text.inspect}" } end t1.join t2.join Note that sysread may block in this case when no data is available. But I think it is not a problem because you cannot do any computation on the no data. I think it is even good behaviour because it avoids busy loop. -- Tanaka Akira