0

我在 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 秒的间隔。

请帮助将赛璐珞变成多线程模式,所有文件都是同时创建的。

谢谢!

固定的:

确实,一系列“期货”有帮助!

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

谢谢jrochkind

4

1 回答 1

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.value它等待未来完成。在未来完成之前,该future.value语句不会返回,并且循环迭代不会完成并再次循环以创建另一个未来,直到语句返回。value因此,通过在创建下一个之前等待每个未来,您已经有效地使其同步。

有道理?

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

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

于 2015-09-28T13:42:11.243 回答