Ruby/Threads/Synchronization
Материал из Wiki.crossplatform.ru
Содержание |
Controlling the Thread Scheduler
class MyData attr_reader :count def initialize(name) @name = name @count = 0 end def chase(other) while @count < 5 while @count < other count > 1 Thread.pass end @count += 1 print "#@name: #{count}\n" end end end c1 = MyData.new("A") c2 = MyData.new("B") threads = [ Thread.new { Thread.stop; c1.chase(c2) }, Thread.new { Thread.stop; c2.chase(c1) } ]
make specific objects into monitors.
require "monitor" class Counter attr_reader :count def initialize @count = 0 end def tick @count += 1 end end c = Counter.new c.extend(MonitorMixin) t1 = Thread.new { 10000.times { c.synchronize { c.tick } } } t2 = Thread.new { 10000.times { c.synchronize { c.tick } } } t1.join; t2.join c.count # 20000
Multithreads without synchronization
x = 0 t1 = Thread.new do 1.upto(1000) do x = x + 1 end end t2 = Thread.new do 1.upto(1000) do x = x + 1 end end t1.join t2.join puts x
Synchronizing Access to an Object
require "thread" class Object def synchronize mutex.synchronize { yield self } end def mutex @mutex ||= Mutex.new end end
This is easy using monitors.
require "monitor" class Counter < Monitor attr_reader :count def initialize @count = 0 super end def tick synchronize do @count += 1 end end end c = Counter.new t1 = Thread.new { 10000.times { c.tick } } t2 = Thread.new { 10000.times { c.tick } } t1.join; t2.join c.count # 20000
Use monitor to lock
require "monitor" class Counter attr_reader :count def initialize @count = 0 end def tick @count += 1 end end c = Counter.new lock = Monitor.new t1 = Thread.new { 10000.times { lock.synchronize { c.tick } } } t2 = Thread.new { 10000.times { lock.synchronize { c.tick } } } t1.join; t2.join c.count # 20000