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