Kernel#fork
static VALUE
rb_f_fork(VALUE obj)
{
rb_pid_t pid;
pid = rb_call_proc__fork();
if (pid == 0) {
if (rb_block_given_p()) {
int status;
rb_protect(rb_yield, Qundef, &status);
ruby_stop(status);
}
return Qnil;
}
return PIDT2NUM(pid);
}
Creates a child process.
With a block given, runs the block in the child process; on block exit, the child terminates with a status of zero:
puts "Before the fork: #{Process.pid}" fork do puts "In the child process: #{Process.pid}" end # => 382141 puts "After the fork: #{Process.pid}"
Output:
Before the fork: 420496 After the fork: 420496 In the child process: 420520
With no block given, the fork call returns twice:
-
Once in the parent process, returning the pid of the child process.
-
Once in the child process, returning
nil.
Example:
puts "This is the first line before the fork (pid #{Process.pid})" puts fork puts "This is the second line after the fork (pid #{Process.pid})"
Output:
This is the first line before the fork (pid 420199) 420223 This is the second line after the fork (pid 420199) This is the second line after the fork (pid 420223)
In either case, the child process may exit using Kernel.exit! to avoid the call to Kernel#at_exit.
To avoid zombie processes, the parent process should call either:
-
Process.wait, to collect the termination statuses of its children. -
Process.detach, to register disinterest in their status.
The thread calling fork is the only thread in the created child process; fork doesn’t copy other threads.
Note that method fork is available on some platforms, but not on others:
Process.respond_to?(:fork) # => true # Would be false on some.
If not, you may use ::spawn instead of fork.