2017-08-10 14 views
1

多くのスレッドを作成して結果をデータ構造体に戻そうとしていますが、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 

コード印刷:(常に少し異なる)私は10

を通じて番号1を期待していた

4 
4 
4 
4 
10 
10 
10 
10 
10 
10 

私は手動で無駄にsynchronizeしようとしていた:

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

私には何が欠けていますか?

+0

ところで、それは右の 'class'ブロックにそのようなコードを入れて奇妙です。それをメソッドでラップする必要があります。 – Stefan

答えて

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 
関連する問題