# How to properly interact with processes?

**URL:** <https://www.ruby-forum.com/t/how-to-properly-interact-with-processes/58584>\
**Category:** Ruby\
**Created:** [April 23, 2006, 5:53pm UTC](https://www.ruby-forum.com/t/how-to-properly-interact-with-processes/58584 "2006-04-23T17:53:28Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![johanati](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/6bbea6/32.png) [@johanati](https://www.ruby-forum.com/u/johanati)\
**Post date:** [April 23, 2006, 5:53pm UTC](https://www.ruby-forum.com/t/how-to-properly-interact-with-processes/58584/1 "2006-04-23T17:53:28Z")

</div>

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
2. Done! from process(864)
3. External process (PID:864) started at: 5.141000s
4. 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).

---

<div class="post-metadata">

**Author:** ![johanati](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/6bbea6/32.png) [@johanati](https://www.ruby-forum.com/u/johanati)\
**Post date:** [April 23, 2006, 6:02pm UTC](https://www.ruby-forum.com/t/how-to-properly-interact-with-processes/58584/2 "2006-04-23T18:02:42Z")

</div>

A thought just struck me, that most people on the mailing list and forum  
seem to be using ruby on some kind of Unix variant (Linux, Solaris, OSX  
…), which got me thinking that perhaps it’s the Windows implementation  
that’s buggy.

Below are my test results from cygwin on win32 and it actually behaves  
correctly!

#===============================================================================

# Using ruby 1.8.4 (2005-12-24) [i386-cygwin]

#===============================================================================

1. Starting external process at: 0.000000s
2. External process (PID:2624) started at: 0.031000s
3. Begun doing something else while proc works at: 0.031000s
4. Done! from process(2624)
5. External proc done at: 5.156000s

#===============================================================================

And for completeness sake, a test on a some what more complete unix-like  
system

#===============================================================================

# ruby 1.8.3 (2005-09-21) [i686-linux]

#===============================================================================

1. Starting external process at: 0.000006s
2. External process (PID:30737) started at: 0.001106s
3. Begun doing something else while proc works at: 0.001216s
4. Done! from process(30737)
5. External proc done at: 5.001349s

#===============================================================================

Now, it’s all good and dandy that the unix-like environments behave  
properly, but I really need have this functioning on win32 as well. So  
if anyone knows how to get the example working properly on windows I’d  
be extremely grateful.

---

<div class="post-metadata">

**Author:** ![johanati](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/6bbea6/32.png) [@johanati](https://www.ruby-forum.com/u/johanati)\
**Post date:** [April 23, 2006, 6:40pm UTC](https://www.ruby-forum.com/t/how-to-properly-interact-with-processes/58584/3 "2006-04-23T18:40:28Z")

</div>

I just saw that the forum destroyed the code by wrapping the lines too  
early. Here is the code with shorter lines.

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  
t  
end

time(“1. Starting external process”)  
CMD = %{ruby -e “sleep 5;puts ‘from process(#{$$})’”}  
t=run\_proc(CMD) {|s|  
puts “4. Done! #{s}”  
}  
time(“2. External process (PID:#{@pid}) started”)  
time(“3. Begun doing something else while proc works”)  
t.join  
time(“5. External proc done”)
