不能 运行 使用 Celluloid 进行多线程处理
Can't run multithreading with Celluloid
这个简单的例子我运行在jruby上,但是它只有一个线程运行s
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 变成多线程模式,所有文件同时创建。
谢谢!
已修复:
确实,"futures" 数组有帮助!
futures = []
TIMES.times do |i|
futures << Celluloid::Future.new { FileWorker.new.create_file(i) }
end
futures.each {|f| p f.value }
谢谢jrochkind!
啊,我想我明白了。
在你的循环中,你在等待每个未来完成,在循环结束时——这意味着你在等待一个未来完成,然后再创建下一个。
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
语句不会 return 直到 future 完成,并且循环迭代不会完成并再次循环以创建另一个 future 直到语句 returns。所以你已经有效地使它同步,通过在创建下一个之前用 value
等待每个未来。
有道理吗?
此外,对于像这样的短代码块,如果您将代码直接放在问题中并正确缩进以格式化为代码,而不是链接出去,那么潜在的 SO 回答者会更容易。
一般来说,如果您正在使用像 Celluloid 这样使用相当广泛的库,并且发现它似乎没有做它应该做的主要事情——第一个猜测可能是您的代码中的错误,并不是说该库根本不起作用(之前其他人可能已经注意到了!)。反映这一点的问题标题,即使只是 "Why doesn't my Celluloid code appear to work multi-threaded" 也可能比暗示 Celluloid 从根本上不起作用的标题更受关注——问题本身没有任何代码来证明!
这个简单的例子我运行在jruby上,但是它只有一个线程运行s
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 变成多线程模式,所有文件同时创建。
谢谢!
已修复:
确实,"futures" 数组有帮助!
futures = []
TIMES.times do |i|
futures << Celluloid::Future.new { FileWorker.new.create_file(i) }
end
futures.each {|f| p f.value }
谢谢jrochkind!
啊,我想我明白了。
在你的循环中,你在等待每个未来完成,在循环结束时——这意味着你在等待一个未来完成,然后再创建下一个。
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
语句不会 return 直到 future 完成,并且循环迭代不会完成并再次循环以创建另一个 future 直到语句 returns。所以你已经有效地使它同步,通过在创建下一个之前用 value
等待每个未来。
有道理吗?
此外,对于像这样的短代码块,如果您将代码直接放在问题中并正确缩进以格式化为代码,而不是链接出去,那么潜在的 SO 回答者会更容易。
一般来说,如果您正在使用像 Celluloid 这样使用相当广泛的库,并且发现它似乎没有做它应该做的主要事情——第一个猜测可能是您的代码中的错误,并不是说该库根本不起作用(之前其他人可能已经注意到了!)。反映这一点的问题标题,即使只是 "Why doesn't my Celluloid code appear to work multi-threaded" 也可能比暗示 Celluloid 从根本上不起作用的标题更受关注——问题本身没有任何代码来证明!