From: Johan Andersen Date: 2006-04-24T00:53:40+09:00 Subject: How to properly interact with processes? I've been trying for three days now to find a proper way of interacting with external processes without a satisfactory result. Thus I turn to the expertise of this group in hope of salvation :-) During my experimentation I've noticed that it seems like when a controlling ruby thread is in an IO-loop, it will block indefinitely if no data is received. The example below shows the problem. def time(s) @st ||= Time.now printf "%s at: %fs\n", s, Time.now - @st end def run_proc(cmd,&callback) t = Thread.new(cmd){ IO.popen(cmd){|p| @pid = p.pid while(s=p.gets) callback.call(s) end } } while(!@pid) do sleep 0.01 end # Ensure the process is started properly t # before allowing the main thread to continue end time("1. Starting external process") t=run_proc('ruby -e "sleep 5;puts %{4. Done! from process(#{$$})}"') {|s| puts s } time("2. External process (PID:#{@pid}) started") time("3. Begun doing something else while proc works") t.join time("5. External proc done") #=============================================================================== # Produces the following output using ruby 1.8.2 (2004-12-25) [i386-mswin32] #=============================================================================== 1. Starting external process at: 0.000000s 4. Done! from process(864) 2. External process (PID:864) started at: 5.141000s 3. Begun doing something else while proc works at: 5.141000s 5. External proc done at: 5.141000s #=============================================================================== In a threaded application one would expect the timings of the resulting lines #1,2 and 3 be close to zero, while only the last timing (#5) should be just above 5 seconds, since the thread join is provided before the last output and the previous timed steps should simply flow through without blocking. Obviously this is not the case. I'm most likely using the wrong IO-mechanism for this task and if so I'd appreciate if someone could give an example using another mechanism for the provided example so that the example behaves as would be expected (i.e. the resulting lines are output in ascending order as per their numbering and their timings being as previously explained). -- Posted via http://www.ruby-forum.com/.