Shay Hawkins wrote: > I call Open3.popen3 to create the three streams. In a loop, I want to > constantly read input from stderr. (Assuming I assigned the pipes to > stdin, stdout, and stderr variable names.) > > loop do > line = stderr.gets() > puts("Output: #{line}") > end > > Then, if I receive an output of say, 0, I want to input something to the > program through stdin five seconds later. > > loop do > line = stderr.gets().strip() > puts("Output: #{line}") > > if(line == "0") > Thread.new() do > sleep(5) > stdin.puts("Received 0 five seconds ago.") > end > end > end > > It creates the thread properly, but when the sleep expires and it is > ready to call stdin.puts(), it cannot do anything, because the loop > continued around and it is reading from stderr. Perhaps it would be helpful to distinguish symptoms from your assumed causes. Firstly, are you saying that the stdin.puts line never completes? You need to prove this. I suggest: STDERR.puts "About to send..." stdin.puts "Received 0" STDERR.puts "Finished sending." Secondly, if the puts never completes, are you sure that an exception is not being raised within your thread? Such exceptions are usually silent, unless you either join the thread (wait for it to complete), or you set Thread.abort_on_exception = true at the top of your program. I suggest you do the latter, to help rule out a possible cause. Thirdly, because of buffering, the stuff you wrote to stdin might not actually be sent until you do stdin.flush Or you could do 'stdin.sync = true' after opening with popen3, so that all writes to stdin are flushed automatically. (So if you see "Finished sending." but the other program doesn't appear to respond, that could be the underlying problem) > However, when it > receives a new set of input from stderr, since the stream is momentarily > being unused, it can then grab the stdin stream and properly input the > old line. So prove that; e.g. the STDERR.puts "Finished sending." I suggested before. > As I mentioned before, I tried using select on stderr so that it > wouldn't tie up the stream, yet I've been told select only works > properly with sockets on Windows. No, if you are using threads, you do not need to do select. Actually, Ruby will be using select() behind the scenes, and so if Windows really is that broken, then you would never be able to run multiple threads talking on different file descriptions; but I didn't think it was quite that broken (you need a Windows expert though, I am not one) If the program really only outputs to stderr and nothing to stdout, then it may be simpler just to redirect stderr to stdout, and then talk to it using a normal IO.popen. That would be "yourcmd 2>&1" under Linux; I don't know what the Windows equivalent would be. Of course, if it weren't for the "5 second delay" requirement, then it could be written quite happily without a thread: while line = stderr.gets line.chomp! puts "Output: #{line}" if line == "0" stdin.puts "Sending something now" stdin.flush end end -- Posted via http://www.ruby-forum.com/.