Process.detach(pid) → thread
Some operating systems retain the status of terminated child processes until the parent collects that status (normally using some variant of wait(). If the parent never collects this status, the child stays around as a zombie process. Process::detach prevents this by setting up a separate Ruby thread whose sole job is to reap the status of the process pid when it terminates. Use detach only when you do not intent to explicitly wait for the child to terminate. detach only checks the status periodically (currently once each second).
In this first example, we don’t reap the first child process, so it appears as a zombie in the process status display.
p1 = fork { sleep 0.1 } p2 = fork { sleep 0.2 } Process.waitpid(p2) sleep 2 system("ps -ho pid,state -p #{p1}")
produces:
27389 Z
In the next example, Process::detach is used to reap the child automatically.
p1 = fork { sleep 0.1 } p2 = fork { sleep 0.2 } Process.detach(p1) Process.waitpid(p2) sleep 2 system("ps -ho pid,state -p #{p1}")
(produces no output)
Source Code
/* * call-seq: * Process.detach(pid) => thread * * Some operating systems retain the status of terminated child * processes until the parent collects that status (normally using * some variant of <code>wait()</code>. If the parent never collects * this status, the child stays around as a <em>zombie</em> process. * <code>Process::detach</code> prevents this by setting up a * separate Ruby thread whose sole job is to reap the status of the * process _pid_ when it terminates. Use <code>detach</code> * only when you do not intent to explicitly wait for the child to * terminate. <code>detach</code> only checks the status * periodically (currently once each second). * * In this first example, we don't reap the first child process, so * it appears as a zombie in the process status display. * * p1 = fork { sleep 0.1 } * p2 = fork { sleep 0.2 } * Process.waitpid(p2) * sleep 2 * system("ps -ho pid,state -p #{p1}") * * <em>produces:</em> * * 27389 Z * * In the next example, <code>Process::detach</code> is used to reap * the child automatically. * * p1 = fork { sleep 0.1 } * p2 = fork { sleep 0.2 } * Process.detach(p1) * Process.waitpid(p2) * sleep 2 * system("ps -ho pid,state -p #{p1}") * * <em>(produces no output)</em> */ static VALUE proc_detach(VALUE obj, VALUE pid) { rb_secure(2); return rb_detach_process(NUM2INT(pid)); }
<code/>and<pre/>for code samples.