# Open3 throws exception when preceded by fork

**URL:** <https://rubytalk.org/t/open3-throws-exception-when-preceded-by-fork/47704>\
**Category:** ruby-talk\
**Created:** [14 July 2008 19:05 UTC](https://rubytalk.org/t/open3-throws-exception-when-preceded-by-fork/47704 "2008-07-14T19:05:26Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![trickyvail](https://avatars.discourse-cdn.com/v4/letter/t/df705f/32.png) [@trickyvail](https://rubytalk.org/u/trickyvail)\
**Post date:** [14 July 2008 19:05 UTC](https://rubytalk.org/t/open3-throws-exception-when-preceded-by-fork/47704/1 "2008-07-14T19:05:26Z")

</div>

I am attempting to create a daemon that (when required) spawns off  
child processes to perform "jobs". It is important that this daemon  
does not block so it can start concurrent jobs, and that it knows when  
jobs have completed. Some of the jobs are written in C++ and send  
their output over standard error (stderr).

Here's an outline of my daemon program.

#!/usr/bin/ruby  
require 'open3'  
stop = false  
Signal.trap('CLD') do  
&nbsp;&nbsp;child = Process.wait  
&nbsp;&nbsp;puts "child #{child} closed."  
&nbsp;&nbsp;stop = true  
end  
child = Kernel.fork()  
if(child == nil)  
&nbsp;&nbsp;stdin, stdout, stderr =  
Open3.popen3('program\_that\_sends\_output\_to\_stderr')  
&nbsp;&nbsp;stderr.each do |line|  
&nbsp;&nbsp;&nbsp;&nbsp;puts line  
&nbsp;&nbsp;end  
&nbsp;&nbsp;Kernel.exit!  
end  
while(! stop)  
&nbsp;&nbsp;sleep 5  
end  
puts "finished"

When tested separately the fork and popen3 calls seem to be just what  
I need to meet my objectives, but when they are run sequentially the  
popen3 call throws an exception:  
Error: "/usr/lib/ruby/1.8/open3.rb:75:in `waitpid': No child processes  
(Errno::ECHILD)"

Is this a limitation of Open3? Any alternative approaches would be  
gratefully received.  
Thank you.

---

<div class="post-metadata">

**Author:** ![a11](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/a11/32/8169_2.png) [@a11](https://rubytalk.org/u/a11)\
**Post date:** [14 July 2008 20:52 UTC](https://rubytalk.org/t/open3-throws-exception-when-preceded-by-fork/47704/2 "2008-07-14T20:52:25Z")

</div>

require 'rubygems'  
require 'slave' # gem install slave

class Server  
&nbsp;&nbsp;&nbsp;def run job  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;system job  
&nbsp;&nbsp;&nbsp;end  
end

slave = Slave.new{ Sever.new }  
server = slave.object

server.run 'echo "this is in another process you do not have to ever worry about"'

a @ [http://codeforpeople.com/](http://codeforpeople.com/)

> **···**
>
> On Jul 14, 2008, at 1:05 PM, trickyvail wrote:
> 
> > s this a limitation of Open3? Any alternative approaches would be  
> > gratefully received.
> 
> --  
> we can deny everything, except that we have the possibility of being better. simply reflect on that.  
> h.h. the 14th dalai lama

---

<div class="post-metadata">

**Author:** ![trickyvail](https://avatars.discourse-cdn.com/v4/letter/t/df705f/32.png) [@trickyvail](https://rubytalk.org/u/trickyvail)\
**Post date:** [14 July 2008 23:50 UTC](https://rubytalk.org/t/open3-throws-exception-when-preceded-by-fork/47704/3 "2008-07-14T23:50:25Z")

</div>

Thank you for you reply. Unfortunately I am unable to utilize the  
slave ruby gem (and open4 gem also) due to some rubygems package  
corruption? on my Ubuntu machine. I've given up fighting with it and  
come up with a different solution.

daemon:  
#!/usr/bin/ruby  
stop = false  
Signal.trap('CLD') do  
&nbsp;&nbsp;child = Process.wait  
&nbsp;&nbsp;puts "child #{child} closed."  
&nbsp;&nbsp;stop = true  
end  
exec('./job.rb') if fork.nil?  
while(! stop)  
&nbsp;&nbsp;puts 'not finished, do some other stuff'  
&nbsp;&nbsp;sleep 5  
end  
puts "finished"

job:  
#!/usr/bin/ruby  
require 'open3'  
stdin, stdout, stderr = Open3.popen3('real\_job\_binary')  
stderr.each do |line|  
&nbsp;&nbsp;puts line  
end

This way the calls to fork and open3 are isolated in different ruby  
interpreter instances where they can't interfere with each other.

> **···**
>
> On Jul 14, 2:52 pm, "ara.t.howard" \<ara.t.how...@gmail.com\> wrote:
> 
> > require 'rubygems'  
> > require 'slave' # gem install slave
> > 
> > class Server  
> > &nbsp;&nbsp;&nbsp;def run job  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;system job  
> > &nbsp;&nbsp;&nbsp;end  
> > end
> > 
> > slave = Slave.new{ Sever.new }  
> > server = slave.object
> > 
> > server.run 'echo "this is in another process you do not have to ever  
> > worry about"'

---

<div class="post-metadata">

**Author:** ![a11](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/a11/32/8169_2.png) [@a11](https://rubytalk.org/u/a11)\
**Post date:** [14 July 2008 23:57 UTC](https://rubytalk.org/t/open3-throws-exception-when-preceded-by-fork/47704/4 "2008-07-14T23:57:58Z")

</div>

the tgz files are on rubyforge. just unpack and run

&nbsp;&nbsp;&nbsp;'sudo ruby install.rb'

cheers.

a @ [http://codeforpeople.com/](http://codeforpeople.com/)

> **···**
>
> On Jul 14, 2008, at 5:50 PM, trickyvail wrote:
> 
> > Thank you for you reply. Unfortunately I am unable to utilize the  
> > slave ruby gem (and open4 gem also) due to some rubygems package  
> > corruption? on my Ubuntu machine. I've given up fighting with it and  
> > come up with a different solution.
> 
> --  
> we can deny everything, except that we have the possibility of being better. simply reflect on that.  
> h.h. the 14th dalai lama
