Как вы порождаете дочерний процесс в Ruby? - PullRequest
34 голосов
/ 21 ноября 2008

Я хочу перенести блок кода из моего основного процесса в дочерний процесс, чтобы он выполнялся одновременно. Я также хочу иметь PID порожденного дочернего процесса, чтобы я мог отслеживать и уничтожать его при необходимости.

Ответы [ 5 ]

41 голосов
/ 21 ноября 2008

В дополнение к отличному ответу Криса, не забудьте позвонить своему хозяину по номеру Process.wait, чтобы пожинать плоды вашего процесса, иначе вы оставите зомби позади.

Пример по запросу в комментариях:

pid = Process.fork do
  puts "child, pid #{Process.pid} sleeping..."
  sleep 5
  puts "child exiting"
end

puts "parent, pid #{Process.pid}, waiting on child pid #{pid}"
Process.wait
puts "parent exiting"
24 голосов
/ 21 ноября 2008

Вы можете использовать метод ядра fork. Вот пример:

#!/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}"

Метод fork возвращает PID процесса, который он разветвляет, и выполняет любой код в переданном блоке. Как и обычные блоки Ruby, он сохраняет привязки родительского процесса.

Это хорошая идея, чтобы сделать ваш раздвоенный процесс exit.

7 голосов
/ 08 октября 2009

В 1.9 вы можете использовать команду Process.spawn. Смотри также http://en.wikibooks.org/wiki/Ruby_Programming/Running_Multiple_Processes

2 голосов
/ 10 апреля 2012

Хорошей альтернативой fork / exec / spawn является гем posix-spawn для Ruby 1.9: https://github.com/rtomayko/posix-spawn

Они проделали большую часть тяжелой работы, чтобы сделать ее более простой, эффективной и гибкой по сравнению с методами более низкого уровня.

2 голосов
/ 21 ноября 2008

Если вы счастливы использовать потоки, а не процессы, то что-то вроде этого может быть немного масштабируемым до более чем одного форка:

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
}

Пожалуйста, ознакомьтесь с отличными комментариями и рекомендациями Джона Топли ниже относительно модели выполнения Ruby и ее ограничений.


Только что отредактировано, чтобы исправить явную ошибку (без назначения на задачу) и следовать совету @ (Джейсона Кинга).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...