Method: Kernel#fork
- Defined in:
- process.c
permalink #fork { ... } ⇒ Integer? #fork ⇒ Integer?
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
.
4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 |
# File 'process.c', line 4377
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);
}
|