初心者的な質問で申し訳ありませんが、よろしくお願いします。
AとBのメソッドがあり、複数のスレッドで非同期的にメソッドが呼ばれています。
AとAが同時に呼ばれるときに排他処理をする必要は無いのですが、AとBが同時に呼ばれては
いけないので、排他処理をする必要があります。
この場合、一般的にはどのように排他すればよいのでしょうか?
Windows環境でWin32APIを使用しています。
同一プロセス内のスレッド間の排他処理には
1.クリティカルセクションで排他処理をする
2.volatileなフラグで排他処理する
等が、すぐに思いつく方法です。
排他制御をどう実装すべきかは、案件(仕様)次第。
後から実行しようとしたほうが待てばいいのか、
優先順をつけて、優先側だけが実行される(非優先側が待つ)のか、
どっちかが待つことでデッドロックになったりしないか、
どのくらいの頻度で呼ばれるのか、
どのくらいのCPU負荷が許されるのか、
などなど考えるべき前提条件はみな違う。だから一般解ってのは無い。
とりあえず CriticalSection で実装するとしたら
EnterCriticalSection LeaveCriticalSection TryEnterCriticalSection
あたりを参照。
> AとBのメソッドがあり、複数のスレッドで非同期的にメソッドが呼ばれています。
うーーん、
まず、完全でなくても同期的に呼ぶようにしたほうがいいですね。
僕の場合、
「CreateEvent()」,「WaitForSingleObjct()」を使って
ある条件の時に制御を開始するようにして、理論上 AとBのメソッドが同時に
呼ばれないようにしていますね。
そのあと、中澤さん・tetrapodさんの意見どおり、リティカルセクション
を使うのがいいと思います。
ただ、条件によってはほかの排他処理が必要な場合もあります。
WINDOWS 同期オブジェクトでぐぐるといいと思います。
うーーん
条件→状況ですね。
失礼しました。
無理矢理ですが、、
c はクリティカルセクションです。
g_a, g_b の読み書きには、 c 以外のクリティカルセクションで排他処理を。
volatile int g_a = 0; // A()を実行しているスレッド数
volatile int g_b = 0; // B()を実行しているスレッド数
A()
{
EnterCriticalSection(c)
g_b が 0 になるまで待機
g_a++;
LeaveCriticalSection(c);
:
A()の処理
:
g_a--;
}
B()
{
EnterCriticalSection(c)
g_a が 0 になるまで待機
Bが同時に呼ばれて困る場合は g_b も 0 になるまで待機
g_b++;
LeaveCriticalSection(c)
:
B()の処理
:
g_b--;
}