From: Michal Suchanek Date: 2008-08-06T21:08:55+09:00 Subject: Threaded IO trouble Hello I do not understand the internals of Ruby IO but what I get here looks really awful. I am interfacing an application that processes lines of text and buffers part of the output until EOF (or EOF tag). I thought using an additional thread would be the right thing to do in this case: one thread writes stuff, and as the application starts to output stuff another thread wakes up to read it. There are two problems here: 1) only reading inside the separate thread is possible, writing causes stdin to be read into the program 2) reading inside the thread produces deadlocks Attaching the files required to reproduce both failures. =================== mock.rb =================== buf=[] while l=gets buf << l puts buf.shift if buf.length >3 end =================== garbage =================== ilks nvd sdh v df bhl dj fbo fj wr;oug rbfg =================== testt.rb =================== def unidentified l false end def try_analyze *words return [] if words.length < 1 analyzer = IO.popen( 'ruby -w mock.rb', IO::RDWR | IO::SYNC ) res = [] t = Thread.new( (IO::for_fd analyzer.fileno) ,res){|fd,ary| while l = fd.gets do break if l =~ %r|^$| if l =~ /^$/ STDERR << "try_analyze: Empty line in output! \n" next else ary.push l end end fd.close rescue nil # hopefully prevents zombie hordes } words.each{|w| STDERR.puts "try_analyze: #{w}" analyzer.puts ""+w } analyzer.puts "" analyzer.close_write t.join res.map{|w| if unidentified w then nil else if w !~ /^"+w } fd.puts "" analyzer.close_write } analyzer.sync = true while l = analyzer.gets do break if l =~ %r|^$| if l =~ /^$/ STDERR << "try_analyze: Empty line in output! \n" next else res.push l end end fd.close rescue nil # hopefully prevents zombie hordes res.map{|w| if unidentified w then nil else if w !~ /^