Общая переменная среди процессов Ruby

У меня есть программа 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 отображает ноль из-за форка.

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


person Jesse Jashinsky    schedule 16.06.2010    source источник
comment
Вы уверены, что это YAML занимает время? Если да, то пытались ли вы загрузить его с помощью Psych, а не Syck?   -  person Andrew Grimm    schedule 15.08.2011


Ответы (4)


Одна проблема заключается в том, что вам нужно использовать 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 } ]

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

person rampion    schedule 16.06.2010
comment
Куда идет символ :hash, когда вы пишете p [:one, @one, :hash, @hash] #=> [ :one, 1, { :one => 1 } ]? - person Jeriko; 17.06.2010
comment
Как мне обмениваться данными между процессом, который запускает инициализаторы Rails, и процессом, который выполняет HTTP-запросы? Все они создаются Phusion Passenger без моего вмешательства. - person Paul; 27.08.2014
comment
Пол: Я не знаком с тем, как они появляются. Возможно, вы захотите перейти к полному вопросу. У меня возникнет соблазн попробовать именованный канал, но, вероятно, есть более простой способ. Может БД? - person rampion; 27.08.2014

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

person maasha    schedule 01.10.2014

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

person regularfry    schedule 16.06.2010
comment
документ: ensta .fr/~diam/ruby/online/ruby-doc-stdlib/libdoc/drb/rdoc/ - person rampion; 17.06.2010

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

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

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

person Trey    schedule 16.06.2010
comment
Потоки - это не то, что мне нужно, потому что они не используют преимущества нескольких ядер. На самом деле я уже пробовал потоки, и это было на самом деле медленнее. - person Jesse Jashinsky; 17.06.2010