Общая переменная среди процессов Ruby - PullRequest
11 голосов
/ 17 июня 2010

У меня есть программа на Ruby, которая загружает два очень больших файла yaml, поэтому я могу получить некоторое ускорение, используя преимущества нескольких ядер, отделяя некоторые процессы.Я пытался посмотреть, но у меня возникают проблемы с определением, как, или даже если, я могу поделиться переменными в разных процессах.

Следующий код является то, что у меня в настоящее время:

@proteins = ""
@decoyProteins = "" 

fork do
  @proteins = YAML.load_file(database)
  exit
end

fork do
  @decoyProteins = YAML.load_file(database)
  exit
end

p @proteins["LVDK"]

P показывает ноль из-за разветвления.

Так возможно ли, чтобы разветвленные процессы разделяли переменные?И если да, то как?

Ответы [ 4 ]

13 голосов
/ 17 июня 2010

Одна проблема заключается в том, что вам нужно использовать Process.wait, чтобы дождаться завершения разветвленных процессов. Другой заключается в том, что вы не можете осуществлять межпроцессное взаимодействие через переменные. Чтобы увидеть это:

@one = nil
@two = nil
@hash = {}
pidA = fork do
    sleep 1
    @one = 1
    @hash[:one] = 1
    p [:one, @one, :hash, @hash] #=> [ :one, 1, :hash, { :one => 1 } ]
end
pidB = fork do
    sleep 2
    @two = 2
    @hash[:two] = 2
    p [:two, @two, :hash, @hash] #=> [ :two, 2, :hash, { :two => 2 } ]
end
Process.wait(pidB)
Process.wait(pidA)
p [:one, @one, :two, @two, :hash, @hash] #=> [ :one, nil, :two, nil, :hash, {} ]

Одним из способов межпроцессного взаимодействия является использование канала (IO::pipe). Откройте его перед вилкой, затем закройте каждую сторону вилки одним концом трубы.

С ri IO::pipe:

    rd, wr = IO.pipe

    if fork
      wr.close
      puts "Parent got: <#{rd.read}>"
      rd.close
      Process.wait
    else
      rd.close
      puts "Sending message to parent"
      wr.write "Hi Dad"
      wr.close
    end

 _produces:_

    Sending message to parent
    Parent got: <Hi Dad>

Если вы хотите поделиться переменными, используйте потоки:

@one = nil
@two = nil
@hash = {}
threadA = Thread.fork do
    sleep 1
    @one = 1
    @hash[:one] = 1
    p [:one, @one, :hash, @hash] #=> [ :one, 1, :hash, { :one => 1 } ] # (usually)
end
threadB = Thread.fork do
    sleep 2
    @two = 2
    @hash[:two] = 2
    p [:two, @two, :hash, @hash] #=> [ :two, 2, :hash, { :one => 1, :two => 2 } ] # (usually)
end
threadA.join
threadB.join
p [:one, @one, :two, @two, :hash, @hash] #=> [ :one, 1, :two, 2, :hash, { :one => 1, :two => 2 } ]

Однако я не уверен, что многопоточность принесет вам какую-либо выгоду, когда вы ограничены вводом-выводом.

1 голос
/ 01 октября 2014

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

0 голосов
/ 17 июня 2010

Возможно, вы захотите использовать поток вместо форка, если хотите поделиться данными.

http://ruby -doc.org / docs / ProgrammingRuby / html / tut_threads.html

Да, и если вы действительно хотите использовать преимущества потоков, вы захотите использовать JRuby.В [c] Ruby 1.9 вы всегда можете взглянуть на волокна.Я не смотрел на них, хотя, я не знаю, если это решение для вас.

0 голосов
/ 17 июня 2010

Можно делить переменные между процессами; DRuby, вероятно, является самым низким способом сделать это.

...