Aren的ruby队列线程安全为什么队列不同步?

时间:2017-08-10 10:45:00

标签: ruby multithreading thread-safety

我正在尝试创建多个线程并在数据结构中返回结果,并且我读到Queue是线程安全的,但是当我运行代码时它不会产生预期的结果。< / p>

require 'thread'

class ThreadsTest
  queue = Queue.new
  threads = []
  for i in 1..10
    threads << Thread.new do 
      queue << i
    end
  end

  threads.each { |t| t.join }

  for i in 1..10
    puts queue.pop()
  end
end

代码打印:(总是有点不同)

4
4
4
4
10
10
10
10
10
10

我期待数字1到10。

我曾尝试synchronize手动无效:

  mutex = Mutex.new
  for i in 1..10
    threads << Thread.new do 
      mutex.synchronize do
        queue << i
      end
    end
  end

我错过了什么?

1 个答案:

答案 0 :(得分:2)

Queue是线程安全的,但您的代码不是。就像变量queue一样,变量i在您的线程中共享,因此线程在循环中更改时引用相同的变量。

要修复它,您可以将变量传递给Thread.new,将其变为线程局部变量:

threads << Thread.new(i) do |i|
  queue << i
end

块中的i会影响外部i,因为它们具有相同的名称。如果您需要,可以使用其他名称(例如|thread_i|)。

输出:

3
2
10
4
5
6
7
8
9
1