2010-06-16 8 views
9

ich ein Ruby-Programm, das zwei sehr große yaml-Dateien lädt, so dass ich kann einige Speed-up erhalten, indem durch abzweigt einige Prozesse Vorteil der mehreren Kerne nehmen. Ich habe versucht, nachzusehen, aber ich habe Probleme herauszufinden, wie oder ob ich Variablen in verschiedenen Prozessen teilen kann.Umgebungsvariablen Unter Ruby-Prozesse

Der folgende Code ist, was ich habe zur Zeit:

@proteins = "" 
@decoyProteins = "" 

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

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

p @proteins["LVDK"] 

P zeigt nil obwohl wegen der Gabel.

Ist es also möglich, dass die gegabelten Prozesse die Variablen teilen? Und wenn ja, wie?

+0

Sind Sie sicher, dass YAML sich die Zeit nimmt? Wenn ja, hast du versucht, es mit Psych anstatt mit Syck zu laden? –

Antwort

13

Ein Problem ist, dass Sie Process.wait zu warten, bis Ihre gegabelt Prozesse abzuschließen verwenden müssen. Zum anderen können Sie keine Interprozesskommunikation über Variablen durchführen. Um dies zu sehen:

@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, {} ] 

Eine Möglichkeit, die Kommunikation zwischen Prozessen zu tun, ist mit einem Rohr (IO::pipe). Öffnen Sie es, bevor Sie Gabel, dann haben Sie jede Seite der Gabel ein Ende des Rohres schließen.

Von 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> 

Wenn Sie Variablen teilen, verwenden Themen:

@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 } ] 

Aber ich bin nicht sicher, ob Threading Sie einen Gewinn erhalten, wenn Sie IO sind gebunden.

+0

Wohin geht das Symbol ': hash', wenn Sie' p [: eins, @ein,: hash, @hash] schreiben # => [: eins, 1, {: eins => 1}] '? – Jeriko

+0

... unsichtbar wegen schlechter Transkription? :) es fest, thx – rampion

+0

Wie kann ich Daten zwischen Prozess teilen, die Rails initializers und ein Prozess läuft, die HTTP-Anforderungen läuft? Sie alle werden von Phusion Passenger ohne meine Einmischung hervorgebracht. – Paul

0

Es ist möglich, Variablen zwischen Prozessen zu teilen; DRuby ist wahrscheinlich die niedrigste Barrier-to-Entry-Methode.

+0

doc: http://www.ensta.fr/~diam/ruby/online/ruby-doc-stdlib/libdoc/drb/rdoc/classes/DRb.html – rampion

0

Sie möchten wahrscheinlich einen Thread anstelle einer Verzweigung verwenden, wenn Sie Daten gemeinsam nutzen möchten.

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

Oh, und wenn Sie wirklich die Vorteile von Threads nehmen möchten, müssen Sie wollen JRuby verwenden. In [c] Ruby 1.9 möchten Sie vielleicht immer noch Fasern betrachten. Ich habe sie jedoch nicht angeschaut, ich weiß nicht, ob es eine Lösung für dich ist.

+1

Themen sind nicht das, was ich will, weil es nicht der Fall ist Nutzen Sie die Vorteile der mehreren Kerne. Ich habe tatsächlich bereits Threads probiert, und es war tatsächlich langsamer. –

1

Cod wird für Inter Process Communication gedacht und ermöglicht es Ihnen, leicht Daten zwischen gegabelten Prozesse zu senden.