无法使用赛璐珞

时间:2015-09-25 11:55:13

标签: ruby multithreading concurrency parallel-processing celluloid

这个简单的例子我在jruby上运行,但它只运行一个线程

require 'benchmark'
require 'celluloid/current'

TIMES = 10

def delay
  sleep 1
  # 40_000_000.times.each{|i| i*i}
end

p 'celluloid: true multithreading?'

class FileWorker
  include Celluloid

  def create_file(id)
    delay
    p "Done!"
    File.open("out_#{id}.txt", 'w') {|f| f.write(Time.now) }
  end
end

workers_pool = FileWorker.pool(size: 10)

TIMES.times do |i|
  # workers_pool.async.create_file(i) # also not happens
  future = Celluloid::Future.new { FileWorker.new.create_file(i) }
  p future.value
end

所有创建的文件都有1秒的间隔。

请帮助将Celluloid转变为多线程模式,同时创建所有文件。

谢谢!

FIXED:

确实,一系列“未来”有帮助!

futures = []
TIMES.times do |i|
   futures << Celluloid::Future.new { FileWorker.new.create_file(i) }
end
futures.each {|f| p f.value }

谢谢 jrochkind

1 个答案:

答案 0 :(得分:2)

啊,我想我明白了。

在你的循环中,你正在等待每个未来完成,在循环结束时 - 这意味着你在创建下一个之前等待一个未来完成。

TIMES.times do |i|
  # workers_pool.async.create_file(i) # also not happens
  future = Celluloid::Future.new { FileWorker.new.create_file(i) }
  p future.value
end

尝试将其更改为:

futures = []
TIMES.times do |i|
   futures << Celluloid::Future.new { FileWorker.new.create_file(i) }
end
futures.each {|f| p f.value }

在你的版本中,考虑循环的第一次迭代 - 你创建一个未来,然后调用等待未来完成的future.valuefuture.value语句在将来完成之前不会返回,并且循环迭代将不会完成并再次循环以创建另一个未来,直到语句返回。所以你有效地使它同步,在创建下一个之前用value等待每个未来。

有意义吗?

此外,对于像这样的短代码块,如果将代码直接放在问题中,正确缩进格式为代码,而不是链接,那么对潜在的SO回复者来说会更容易。

一般来说,如果你使用一个相当广泛使用的类似Celluloid的库,并且发现它似乎没有做它应该做的主要事情 - 第一个猜测应该是你的代码中的一个错误,而不是图书馆从根本上根本不起作用(其他人之前会注意到!)。一个问题标题反映出,即使只是“为什么我的赛璐珞代码看起来不像多线程”也可能比标题暗示赛璐珞根本不起作用得到更多的关注 - 没有任何代码在问题本身展示!