I want to offload a block of code in my main process to child process to make it run concurrently. I also want to have the PID of the spawned child process so I can monitor and kill it if necessary.
-
You can use the
forkkernel method. Here is an example:#!/usr/bin/env ruby puts "This is the master process." child_pid = fork do puts "This is the child process" exit end puts "The PID of the child process is #{child_pid}"The
forkmethod returns the PID of the process it forks and executes any code in the block passed. Like regular Ruby blocks it keeps the bindings of the parent process.It is a good idea to make your forked process
exit.Daemin : One thing to remember with Ruby is that not all things work exactly the same way in Windows versus *nix. Sometimes they're completely unimplemented on Windows, so use at your own peril.vava : This one wouldn't work in Windows at allChris Lloyd : @Vadim I think that is a feature, not a bug. -
In addition to Chris' great answer, remember to call
Process.waitfrom your master in order to reap your child process, else you'll leave zombies behind.Chris Lloyd : Sweet, that was an awesome tip. -
If you are happy to use Threads, rather than Processes, then something like this may be a bit more scaleable to more-than-one fork:
def doit(x) sleep(rand(10)) puts "Done... #{x}" end thingstodo = ["a","b","c","d","e","f","g"] tasklist = [] # Set the threads going thingstodo.each { |thing| task = Thread.new(thing) { |this| doit(this) } tasklist << task } # Wait for the threads to finish tasklist.each { |task| task.join }Please see John Topley's excellent comments and reference, below, regarding the Ruby execution model and its restrictions.
Just edited to correct a glaring error (no assignment to task), and to follow @(Jason King)'s advice.
John Topley : Presumably these are Green Threads rather than proper OS threads?John Topley : Read this regarding Ruby 1.9: http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/Jason King : Should be: `Thread.new(thing) { |it| doit(it) }` Because `thing` is reset on each iteration, so there's no guarantee that the right thread will get the right `thing` -
In 1.9 you can use Process.spawn command
0 comments:
Post a Comment