不是 ruby​​ 队列线程安全为什么队列不同步?

MRe*_*ezk 3 ruby multithreading thread-safety

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

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
Run Code Online (Sandbox Code Playgroud)

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

4
4
4
4
10
10
10
10
10
10
Run Code Online (Sandbox Code Playgroud)

我期待数字 1 到 10。

synchronize手动尝试过但无济于事:

  mutex = Mutex.new
  for i in 1..10
    threads << Thread.new do 
      mutex.synchronize do
        queue << i
      end
    end
  end
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Ste*_*fan 5

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

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

threads << Thread.new(i) do |i|
  queue << i
end
Run Code Online (Sandbox Code Playgroud)

i块内阴影外i,因为它们具有相同的名称。|thread_i|如果两者都需要,您可以使用另一个名称(例如)。

输出:

3
2
10
4
5
6
7
8
9
1
Run Code Online (Sandbox Code Playgroud)