2010-06-16 3 views
9

J'ai un programme Ruby qui charge deux fichiers yaml très volumineux, ce qui me permet d'accélérer les choses en tirant parti des multiples cœurs en supprimant certains processus. J'ai essayé de chercher, mais j'ai du mal à comprendre comment, ou même si, je peux partager des variables dans différents processus.Variable partagée parmi les processus Ruby

Le code suivant est ce que j'ai actuellement:

@proteins = "" 
@decoyProteins = "" 

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

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

p @proteins["LVDK"] 

P affiche nil si à cause de la fourche.

Alors est-il possible que les processus forkés partagent les variables? Et si oui, comment?

+0

Etes-vous sûr que c'est YAML qui prend le temps? Si oui, avez-vous essayé de le charger avec Psych plutôt que Syck? –

Répondre

13

Un problème est que vous devez utiliser Process.wait pour attendre la fin de vos processus bifurqués. L'autre est que vous ne pouvez pas faire de communication interprocess à travers des variables. Pour voir ceci:

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

Une façon de faire la communication interprocessus utilise un tuyau (IO::pipe). Ouvrez-le avant de débourrer, puis faites que chaque côté de la fourche ferme une extrémité du tuyau.

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

Si vous souhaitez partager des variables, des fils d'utilisation:

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

Cependant, je ne suis pas sûr si le filetage vous obtiendrez un gain lorsque vous êtes IO lié.

+0

Où va le symbole ': hash', quand vous écrivez' p [: one, @one,: hash, @hash] # => [: one, 1, {: one => 1}] '? – Jeriko

+0

... invisible en raison d'une mauvaise transcription? :) corrigé, thx – rampion

+0

Comment partager des données entre un processus qui exécute des initialiseurs Rails et un processus qui exécute des requêtes HTTP? Tous sont engendrés par Phusion Passenger sans mon interférence. – Paul

0

Il est possible de partager des variables entre les processus; DRuby est probablement le moyen le plus bas pour le faire.

+0

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

0

Vous souhaitez probablement utiliser un thread au lieu d'une fourche si vous souhaitez partager des données.

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

Oh, et si vous voulez vraiment profiter de fils que vous aurez envie d'utiliser JRuby. Dans [c] Ruby 1.9, vous pouvez toujours vouloir regarder les fibres. Je ne les ai pas regardés cependant, je ne sais pas si c'est une solution pour vous.

+1

Les fils ne sont pas ce que je veux, car ils ne le sont pas profiter des multiples cœurs. J'ai déjà essayé des threads, et c'était en fait plus lent. –

1

Cod est destiné à la communication entre processus et vous permettra d'envoyer facilement des données entre des processus fourchus.

Questions connexes