当初はあるクラスのスレッド間で1秒ごとにシーケンシャル処理を行いたいというものだった。
# a.rb
class A
@m = Mutex.new
def get
self.class.instance_variable_get(:@m).synchronize do
sleep 1
puts "#{Time.now} => #{self.class.name}"
end
end
end
# do.rb
require_relative './a'
require_relative './b' # Aとはクラス名のみ異なる。
ps = [A, B]
ts = []
5.times do
ps.each do |prog|
t = Thread.new do
prog.new.get
end
ts << t
end
end
ts.each { |t| t.join }
do.rbの実行結果は次のとおり。
$ ruby do.rb
2016-02-03 18:10:30 +0900 => A
2016-02-03 18:10:30 +0900 => B
2016-02-03 18:10:31 +0900 => B
2016-02-03 18:10:31 +0900 => A
2016-02-03 18:10:32 +0900 => B
2016-02-03 18:10:32 +0900 => A
2016-02-03 18:10:33 +0900 => A
2016-02-03 18:10:33 +0900 => B
2016-02-03 18:10:34 +0900 => B
2016-02-03 18:10:34 +0900 => A
- Aのスレッド間では1秒ごとにメソッドが実行されている。
- Bのスレッド間では1秒ごとにメソッドが実行されている。
ただ、この全部のスレッドで1秒ごとに処理を実行したいという変更が入ったため変更。
今回はモジュール変数で対応した。
# synchronizable.rb
module Synchronizable
@@m = Mutex.new
def m
@@m
end
end
# a2.rb
require_relative './synchronizable'
class A2
include Synchronizable
def get
m.synchronize do
sleep 1
puts "#{Time.now} => #{self.class.name}"
end
end
end
# do2.rb
require_relative './a2'
require_relative './b2' # A2とはクラス名のみ異なる
ps = [A2, B2]
ts = []
5.times do
ps.each do |prog|
t = Thread.new do
prog.new.get
end
ts << t
end
end
ts.each { |t| t.join }
do2.rbの実行結果
$ ruby do2.rb
2016-02-03 18:24:44 +0900 => B2
2016-02-03 18:24:45 +0900 => B2
2016-02-03 18:24:46 +0900 => A2
2016-02-03 18:24:47 +0900 => A2
2016-02-03 18:24:48 +0900 => A2
2016-02-03 18:24:49 +0900 => B2
2016-02-03 18:24:50 +0900 => A2
2016-02-03 18:24:51 +0900 => B2
2016-02-03 18:24:52 +0900 => A2
2016-02-03 18:24:53 +0900 => B2
すべてのスレッドで1秒ごとに処理が実行されている。
0 件のコメント:
コメントを投稿