From: Yusuke ENDOH Date: 2011-03-08T21:31:10+09:00 Subject: [ruby-dev:43333] Re: [Ruby 1.9 - Bug #4474] 複数のスレッドからトランザクションに入ろうとした場合のPStoreの挙動 遠藤です。 2011年3月7日9:47 Masaki Matsushita : > sora_hさんが書いたパッチと異なる点は、トランザクションに入っているスレッドがあるかどうかを格納しているインスタンス変数@transactionを廃して、 > Mutexがロックされているかどうかでトランザクションに入っているスレッドがあるかどうかを判定している点です。 > また、第2引数thread_safeの真偽に関わらずトランザクション内の処理をMutexで同期しますが、互換性の為、thread_safeが偽である場合にトランザクションを入ろうとすると例外nested transactionが発生するようにしてあります。 ちょっとだけ考古学してみました。Hongli Lai の元記事がこちら。 http://izumi.plan99.net/blog/index.php/2008/03/26/making-pstore-reaaaally-fast/ とにかく高速化したかったみたいですね。最後に "I’ll send a patch to ruby-core so that this can be merged back upstream" とあるけれど、 そのメールは見つかりませんでした。matz が勝手に (または ruby-core 以外で話をして) 取り込んだんですかね。 r26673 で thread_safe が全然動いてなかったお粗末なバグが修正されて いることから、Hongli Lai は thread_safe のテストを全くやらなかった と思われます。なので、thread_safe のときにも nested transation 例外 が投げられるのは特に意図はしていなさそうな気がします。 PStore#initialize の rdoc を見ると、 # PStore objects are always reentrant. But if _thread_safe_ is set to true, # then it will become thread-safe at the cost of a minor performance hit. とあり、元の目的が超高速化なだけあって、Mutex のロックのコストを気に しているようです。ケチな話ですね。そういう意味で、 > インスタンス変数@transactionを廃して、 > Mutexがロックされているかどうか の変更は、少なくとも Hongli Lai の望むところではなさそうです。 少なくとも、上の rdoc は嘘になっているので修正する必要があります。 一応、Mutex#synchronize は DummyMutex より 2 倍以上遅いみたいです。 1 回あたりを考えるともともと無視できそうなコストですが、PStore のよ うな用途だと問題になりうるんですかね。 $ time ./ruby -e ' class DummyMutex def synchronize yield end end m = DummyMutex.new 1000000.times { m.synchronize { } } ' real 0m0.219s user 0m0.200s sys 0m0.012s $ time ./ruby -e ' m = Mutex.new 1000000.times { m.synchronize { } } ' real 0m0.527s user 0m0.492s sys 0m0.004s Hongli Lai は ruby-core でちょくちょく見かける人なので、聞けば返事を してくれるんじゃないでしょうか。この話は ruby-core で議論した方がいい のでは。 -- Yusuke Endoh