【发布时间】:2012-04-30 20:03:02
【问题描述】:
当我第一次发现线程时,我尝试通过在多个线程中调用 sleep 来检查它们是否确实按预期工作,而不是正常调用 sleep。它奏效了,我很高兴。
但后来我的一个朋友告诉我,这些线程并不是真正并行的,而且 sleep 一定是在假装它。
所以现在我写了这个测试来做一些真正的处理:
class Test
ITERATIONS = 1000
def run_threads
start = Time.now
t1 = Thread.new do
do_iterations
end
t2 = Thread.new do
do_iterations
end
t3 = Thread.new do
do_iterations
end
t4 = Thread.new do
do_iterations
end
t1.join
t2.join
t3.join
t4.join
puts Time.now - start
end
def run_normal
start = Time.now
do_iterations
do_iterations
do_iterations
do_iterations
puts Time.now - start
end
def do_iterations
1.upto ITERATIONS do |i|
999.downto(1).inject(:*) # 999!
end
end
end
现在我很伤心,因为 run_threads() 不仅没有比 run_normal 执行得更好,它甚至更慢!
如果线程不是真正并行的,我为什么要让我的应用程序复杂化呢?
** 更新 **
@fl00r 说如果我将线程用于 IO 任务,我可以利用它们,所以我又写了两个 do_iterations 的变体:
def do_iterations
# filesystem IO
1.upto ITERATIONS do |i|
5.times do
# create file
content = "some content #{i}"
file_name = "#{Rails.root}/tmp/do-iterations-#{UUIDTools::UUID.timestamp_create.hexdigest}"
file = ::File.new file_name, 'w'
file.write content
file.close
# read and delete file
file = ::File.new file_name, 'r'
content = file.read
file.close
::File.delete file_name
end
end
end
def do_iterations
# MongoDB IO (through MongoID)
1.upto ITERATIONS do |i|
TestModel.create! :name => "some-name-#{i}"
end
TestModel.delete_all
end
性能结果还是一样:正常>线程。
但现在我不确定我的虚拟机是否能够使用所有内核。等我测试完再回来。
【问题讨论】:
-
线程糟透了,纤维摇滚! :D
-
用官方的ruby,线程是伪造的,但是对于jruby和rubinius,我相信是真正的线程。
-
性能并不是使用线程的唯一原因。看我的回答。
标签: ruby multithreading parallel-processing