On Tue, 6 Mar 2007, Anders Lindgren wrote: > Hi! > > I'm implementing an application where the main Ruby program spawns off a > number of external programs using pipes. Each pipe is handled by its own > thread. Well, so far so good... Unfortunately, I'm having problems since > when one thread calls "pipe.each_line" the other (!) threads hang. Well, if > I add a "Process.waitpid" call before the call to pipe.each_line then the > external command will sooner or later hang since noone consumes anything in > the pipe. > > To exemplify, below are two ruby programs. The first, lotsoflines.rb, will > print so much output that the pipe will be filles (in the real world this is > typically not written in Ruby). The second, test.rb, without the "waitpid" > will block the thread printing "BG Thread"; with the "waitpid" line the > background process will never terminate. > > So, what I would need is a way to read from the pipe *without blocking other > threads*, or a wait until there is data to read, or similar. All suggestions > are welcome! > > Oh, btw, I need this to work both under win32 and unix. it can't be done using popen and threads with current ruby. search the archives. this may help http://codeforpeople.com/lib/ruby/systemu/systemu-1.0.0/README gem install systemu > > -- Anders Lindgren > > ------------------------------------ lotsoflines.rb > ARGV[0].to_i.times do puts "A LINE" end > sleep 2 > ------------------------------------ test.rb > cmd = "ruby lotsoflines.rb 300" > > Thread.new do > while true > sleep 0.1 > puts "BG Thread" > end > end > > puts "Before popen" > > IO.popen(cmd) do |pipe| > > puts "Inside popen" > > # With this line, the background thread will be blocked, with this > # line the process at the other end of the pipe will hang... > > Process.waitpid(pipe.pid) > > pipe.each_line do |x| > puts "XXX:" + x > end > end > > puts "After popen" > > -a -- be kind whenever possible... it is always possible. - the dalai lama