[#43284] [Ruby 1.9 - Bug #4456] [Open] Time#strftime で %F 指定子に大きな幅を指定した際の不具合 — tadayoshi funaba <redmine@...>

14 messages 2011/03/02

[#43317] [Ruby 1.9 - Bug #4474][Open] 複数のスレッドからトランザクションに入ろうとした場合のPStoreの挙動 — Masaki Matsushita <redmine@...>

9 messages 2011/03/06

[#43327] [Ruby 1.9 - Feature #4483][Open] PStoreをデフォルトで複数のスレッドから扱えるようにしたい — Masaki Matsushita <redmine@...>

10 messages 2011/03/08

[#43365] [Ruby 1.9 - Bug #4536][Open] 定数参照について1.8と1.9の違い — Yukihiro Matsumoto <matz@...>

11 messages 2011/03/29

[ruby-dev:43336] [Ruby 1.9 - Bug #4474] 複数のスレッドからトランザクションに入ろうとした場合のPStoreの挙動

From: Masaki Matsushita <redmine@...>
Date: 2011-03-10 09:06:53 UTC
List: ruby-dev #43336
Issue #4474 has been updated by Masaki Matsushita.


私も試してみましたが、確かにMutexはDummyMutexと比べて2倍程度遅いようです。

しかし、次のコード

 require 'benchmark'
 require 'pstore'
 
 pd = PStore.new("foo") #DummyMutex
 pm = PStore.new("bar", true) #Mutex
 
 pd.transaction { pd["hoge"] = 0 }
 pm.transaction { pm["hoge"] = 0 }
 
 N = 1000
 
 Benchmark.bmbm do |x|
   x.report("DummyMutex") do
     N.times do
       pd.transaction { pd["hoge"] += 1 }
     end
   end
   x.report("Mutex") do
     N.times do
       pm.transaction { pm["hoge"] += 1 }
     end
   end
 end

をruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux]で実行したところ

 Rehearsal ----------------------------------------------
 DummyMutex   0.020000   0.270000   0.290000 (  0.424386)
 Mutex        0.080000   0.250000   0.330000 (  0.468132)
 ------------------------------------- total: 0.620000sec

                 user     system      total        real
 DummyMutex   0.100000   0.240000   0.340000 (  0.476209)
 Mutex        0.110000   0.210000   0.320000 (  0.469675)

という結果となりました。
トランザクションの出入りに関わる処理全体として見るとあまり大きな差とはなっていないように思えます。

次のコード

 require 'pstore'

 p = PStore.new("foo", true)
 p.transaction { p["hoge"] = 0 }

 1000.times do
   p.transaction { p["hoge"] += 1 }
 end

をプロファイルしたところ、

 %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 64.25     1.42      1.42     1001     1.42     1.42  File#truncate
  3.62     1.50      0.08     2003     0.04     0.05  Digest::Instance.digest
  3.17     1.57      0.07     2003     0.03     0.09  Digest::Class#digest
  3.17     1.64      0.07     1001     0.07     1.67  PStore#save_data
  3.17     1.71      0.07     1001     0.07     0.20  PStore#load_data
  2.26     1.76      0.05     1001     0.05     2.03  Mutex#synchronize
(以下略)

となっており、Mutexによるロックは時間的に多くを占めるものではないようです。
以上のような結果も併せて、ruby-coreの方にも投稿してみようと思います。
----------------------------------------
Bug #4474: 複数のスレッドからトランザクションに入ろうとした場合のPStoreの挙動
http://redmine.ruby-lang.org/issues/4474

Author: Masaki Matsushita
Status: Closed
Priority: Normal
Assignee: 
Category: lib
Target version: 
ruby -v: -


PStoreは、initializeの第2引数thread_safeが真であればデータベースの読み書きをMutexで同期するようになっています。
しかし、次のコード

require 'pstore'
require 'thread'

pstore = PStore.new("foo", true)
q = Queue.new

Thread.start do
  pstore.transaction do
    pstore[:hoge] = "fuga"
    q.push(nil)
    sleep
  end
end

q.pop
pstore.transaction do
  p pstore[:hoge]
end

を実行すると例外が発生します。

/usr/local/lib/ruby/1.9.1/pstore.rb:321:in `transaction': nested transaction (PStore::Error)
        from pstore.rb:16:in `<main>'

以下のコードはpstore.rbの319行目以降から抜粋したものです。

319  def transaction(read_only = false, &block)  # :yields:  pstore
320    value = nil
321    raise PStore::Error, "nested transaction" if @transaction
322    @lock.synchronize do
      (中略)
348    end
      (中略)
352  end

Mutexで保護されたセクションに入る前に、別のトランザクションが実行されていないかどうか調べています。
あるスレッドがトランザクションを実行中に別のスレッドがトランザクションに入ろうとすると、ここで例外が発生します。
thread-safeの定義にも依りますが、これはバグではないでしょうか?


-- 
http://redmine.ruby-lang.org

In This Thread