Threadの同期。
カフェでラスクを食べた。ラスクを前歯でシャクシャクと食べていると、リスになったような気分が味わえるのが好きだ。
昨日に引き続きThread。Threadの同期をやってみる。ほぼ写経。
#!/usr/bin/env ruby class Counter attr_reader:count def initialize @count = 0 end def tick @count += 1 end end counter = Counter.new thread1 = Thread.new { 100000.times { counter.tick }} thread2 = Thread.new { 100000.times { counter.tick }} thread1.join thread2.join p counter.count
結果。
131013
もういっちょ。
142144
使えねぇ。
こうなるのは
@count += 1
1つめのスレッドが@count = 1の状態で実行したとして、2つめのスレッドは@count = 2に対して+1して欲しいけど、同時に実行され、@count = 1の状態で実行されてしまうことがあるため。
これを防ぐためには
@count += 1
を複数のスレッドで同時に実行できないようにする必要がある。
#!/usr/bin/env ruby require 'monitor' # Monitorクラスを継承 class Counter < Monitor attr_reader:count def initialize @count = 0 # 忘れたらdeadlockが発生したので忘れずに super end def tick # 複数のスレッドで同時に処理を行わないようにする synchronize do @count += 1 end end end counter = Counter.new thread1 = Thread.new { 100000.times { counter.tick }} thread2 = Thread.new { 100000.times { counter.tick }} thread1.join thread2.join p counter.count
結果。
200000
おけ。
- 作者: Dave Thomas,Chad Fowler,Andy Hunt,まつもとゆきひろ,田和勝
- 出版社/メーカー: オーム社
- 発売日: 2006/08/26
- メディア: 大型本
- 購入: 7人 クリック: 270回
- この商品を含むブログ (152件) を見る