けいじゅ@いそうろう.日本ラショナルです. In [ruby-list :03649 ] the message: "[ruby-list:3649] [Q] How to use Synchronizer? ", on Aug/10 21:31(JST) shugo / po.aianet.ne.jp (maeda shugo) writes: >前田です。 > >Mutexを使うと > >$m = Mutex.new >def foo > $m.synchronize do > print "foo\n" > end >end >3.times do > $m.synchronize do > foo > end >end > >のようなのがうまく動きませんよね? ですね. >Mutexの代りにSynchronizerを使ってみたらうまくいったのですが、 >Synchronizerではこういった場合の動作も保証されているのでしょうか? 保証されています. ただし, カウントを数えているのでlockの数だけunlockを 行わないとlockが解除されません. >それと、modeの指定の意味がわからないのですが、どうやって使うもの >なのでしょう? そうですね. 説明って全然ないですよね... Syncronizerは(カウント付)2-phase lockを採用しています. mode: :UN ロックの解除 :SH 共有ロック :EX 排他ロック :EXがMutexのロックと同じモードです. このロックがかかっている時に, 他の スレッドがロックしようとするとブロックされます. 排他ロックはwrite lock ともいいます. 書き込み中に他のクライアント(スレッド)が読み/書きすると 危険ですよね. :SHは共有ロックでflockのLOCK_SHと同じものだと思います. このロックがか かっている時は, 以下の動作をします: * 他のスレッドが共有ロックを行おうことはできる. * 他のスレッドが排他ロックを行おうとすると, ブロックされる. 共有ロックは read lock とも呼ばれます. 読み込みの場合, 同時に複数のク ライアント(スレッド)が読み込んでも安全ですが, 書き込みが行われると不整 合が発生する可能性があるのでwrite はblockされるようになっています. 普通の2-phase lockと違うところは, countがついているところなのですが: カウントはどうなっているかというと, カウントは2種類あって read-lock-countとwrite-lock-count があります. 動作はどうなっているかと いうと以下の例を見て下さい:: R: 共有ロック(read-lock) W: 排他ロック(write-lock) Rn: 共有ロックカウント Wn: 排他ロックカウント case 1: ロックの種類:R R R UL UL UL カウントの数:->(R1, W0)->(R2, W0)->(R3, W0)->(R2, W0)->(R1, W0)->(R0, W0) という感じでロックを行うとカウントが増えて, アンロックするとカウントが 減ります. case 2: ロックの種類:W W W UL UL UL カウントの数:->(R0, W1)->(R0, W2)->(R0, W3)->(R0, W2)->(R0, W1)->(R0, W0) 排他ロックの場合も同じです. 問題なのが共有ロックと排他ロックが混在した 時です: case 3: ロックの種類: R -> R -> W -> UL -> UL -> UL カウントの数: (R1, W0)->(R2, W0)->(R2, W1)->(R2, W0)->(R1, W0)->(R0, W0) write lockが行われた時点で, lockのモードが排他ロックにアップグレードさ れます. unlockは, ロックをかけた順番の逆順に解除されます. この場合, 1度めの unlockで排他lockが解除され, 残り2回unlockを行うと共有ロックが解除され ます. あくまでも, ロックをかけた逆順番にロックが解除されるので, 注意が必要で す. Synchronizer#syncを使っている限り問題はないと思いますが... case 4: ロックの種類: R -> W -> R -> UL -> UL -> UL カウントの数: (R1, W0)->(R1, W1)->(R1, W2)->(R1, W1)->(R1, W0)->(R0, W0) 排他ロックの後にかけたロックは, 常に排他ロックとなります. この場合, 2度めのunlockで排他ロックが解除され, 3度めのunlockで共有ロッ クが解除されます. PS. 現在, Synchronizerをversion up中です. Mutex_mのような機能をつけようと しています. あと, case 3の注意事項がちょっと気になるので, unlockにモードもつけられ るようにしたいと思います. __ ..........................................石塚 圭樹@日本ラショナル... ----------------------------------->> e-mail: keiju / bc.mbn.or.jp <<---