我有一个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
显示为nil。
那么分叉进程可以共享变量吗?如果是这样,怎么样?
答案 0 :(得分:13)
一个问题是您需要使用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 } ]
但是,我不确定当你受到IO限制时,线程是否能为你带来任何好处。
答案 1 :(得分:1)
Cod用于进程间通信,允许您在分叉进程之间轻松发送数据。
答案 2 :(得分:0)
可以在进程之间共享变量; DRuby可能是进入障碍的最低障碍。
答案 3 :(得分:0)
如果要共享数据,可能需要使用线程而不是fork。
http://ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html
哦,如果你真的想利用线程,你会想要使用JRuby。在[c] Ruby 1.9中你可能总是想看一下光纤。我没有看过它们,我不知道它是否适合你。