少し複雑な排他処理の方法


マサ  2011-07-01 10:33:44  No: 72792  IP: 192.*.*.*

DB関係のリソースを操作するメソッド A(1スレッドから呼ばれる)
DBのリソースを使用するメソッドB(複数のスレッドから呼ばれる)

上記の場合、AとBのメソッドが同時に呼ばれて欲しくないので排他処理が必要です。
しかし、Bのメソッド同士は排他処理は必要ありません。

この場合、どのように排他処理を行うのが効率的になるのでしょうか?
例えば、グローバルな1つのクリティカルセクションを作成した場合、B同士も排他処理の対象になってしまいます。
Bのスレッド分のオブジェクトハンドルを作成して、WaitForSingleObject、SetEvent、ResetEventを使用して
AとB間のオブジェクトシグナルを判定するしかないのでしょうか?  もう少し簡単な方法があれば御教授願いたいです。

編集 削除
仲澤@失業者  2011-07-01 12:00:12  No: 72793  IP: 192.*.*.*

「メソッドB」がリエントラントであるならば「メソッドB」を
所有し、それを何回コールしているか管理する「親B」が必要なのでは
ないでしょうか。「メソッドB」を使用するスレッドは「親B」経由で
呼ぶようにします。「親B」は「メソッドB」のコール回数が0の時
「メソッドA」に対して同期オブジェクトを排他コントロールします。
「メソッドA」は同じ同期オブジェクトに対して排他コントロールします。

親B()
{
  static int B_Call_Cnt = 0;
  if( 0 == B_Call_Cnt){  Lock_A_with_blocking();}
  B_Call_Cnt++;
  B();    //「メソッドB」
  B_Call_Cnt--;
  if( 0 == B_Call_Cnt)   Unlock_A();
}

編集 削除
オショウ  2011-07-01 12:32:23  No: 72794  IP: 192.*.*.*

DBって何使ってますか?
OSは?

DB側でトリガとストアド使った方が安全に排他制御
できると思いますが・・・

以上。参考まで

編集 削除
bigbro  2011-07-01 18:21:36  No: 72795  IP: 192.*.*.*

なぜDBのトランザクション排他制御機構を使わないのでしょうか?また、DBの排他制御機構では不足なのでしょうか?
serializableなロックをトランザクションにかければOKのような気がしますが。

マサさんはDBにおける排他制御ポリシーが複数あることをご存知でしょうか?デッドロックやダーティーリードなどを防ぐレベルごとにロック機構が複数DBにはあると思いますが、とりあえずserializableにしておけば大体はOKかと。まぁCPUコストは増えるかもしれませんけど。
聞いた感じだとDB側の処理にトランザクションではなく単発命令を使っているのでそのような複雑な方針になってしまったのでは?

OSのリソース排他制御機構を用いてやるというのも処理によっては面白いのかもしれませんが・・・

編集 削除
επιστημη  URL  2011-07-01 22:58:25  No: 72796  IP: 192.*.*.*

スレッドの排他制御を使うなら readers-writer-lock でいけそうな。
http://msdn.microsoft.com/en-us/library/aa904937(v=vs.85).aspx

編集 削除