From: Masatoshi SEKI Date: 2000-08-04T01:01:17+09:00 Subject: [ruby-list:24084] Thread.exclusive [again?] 咳といいます。 大昔('97くらい)の原さんたちの Thread のスレッド、 ちょっと昔('99)のConditionVariableのスレッドを読み返してました。 で、いまさらっぽいですが、thread.rb の Thread.exclusive の話です。 1 def Thread.exclusive 2 begin 3 Thread.critical = true 4 r = yield 5 ensure 6 Thread.critical = false 7 end 8 r 9 end 現状では 6 で前の状態にかかわらず false にしてしまいます。 1.4.6-previewのweakref.rb の様に、前の値をコピーしておいて 復元したほうが良いのではないでしょうか? 1 def Thread.exclusive 2 _old = Thread.critical 3 begin 4 Thread.critical = true 5 return yield 6 ensure 7 Thread.critical = _old 8 end 9 end 解説) 2. 前の値のコピー。weakref.rb と違って begin ... ensure ... end の 外でやってます。_oldが不定のまま ensure されないため。 5. yieldの結果を返します。r にコピーしなくても問題ないですよね ? 7. 前の値の復元。 ところで、weakref.rb の方式って 2 _old = Thread.critical 3 begin 4 Thread.critical = true の間に別スレッドが Thread.critical を変更してしまうと _old が おかしくなりそうな気がするんですけど、実はうまくいくのですよね? # 咳は一瞬うまく動かない感じがしました。私だけか…。 なんでうまくいくかというと … o 2.の瞬間、 Thread.critical == true の場合、そもそも別スレッドに 移らないので安心。 o 2.の瞬間、 Thread.critical == false の場合、4が完了するまでに 変更される可能性があるけど、別スレッドがtrueにした場合は そのスレッドしか動かない、自分に戻ってきたときには false のはずなので だいじょぶ。 考え方あってますでしょうか ?? Thread.exclusive に渡すブロックでスレッドをスイッチさせたら まずいけど、Thread.exclusive みたいに危ないのを使う人は 気をつけて書きますよね。