上位層から呼び出すことができる 3 つの関数があるとします。
Start
- まだ開始されていない場合、または Stop が以前に呼び出された場合にのみ呼び出されますStop
- Start の呼び出しが成功した後にのみ呼び出されますProcess
-いつでも(異なるスレッドで同時に) 呼び出すことができます。開始された場合、下位層を呼び出します
では、すべての呼び出しが下位層への呼び出しを終了するまでStop
待機し、それ以上の呼び出しを防止する必要があります。Process
ロック メカニズムを使用すると、次の疑似コードを作成できます。
Start() {
ResetEvent(&StopCompleteEvent);
IsStarted = true;
RefCount = 0;
}
Stop() {
AcquireLock();
IsStarted = false;
WaitForCompletionEvent = (RefCount != 0);
ReleaseLock();
if (WaitForCompletionEvent)
WaitForEvent(&StopCompleteEvent);
ASSERT(RefCount == 0);
}
Process() {
AcquireLock();
AddedRef = IsStarted;
if (AddedRef)
RefCount++;
ReleaseLock();
if (!AddedRef) return;
ProcessLowerLayer();
AcquireLock();
FireCompletionEvent = (--RefCount == 0);
ReleaseLock();
if (FilreCompletionEvent)
SetEvent(&StopCompleteEvent);
}
ロック機構なしで同じ動作を実現する方法はありますか? おそらく、InterlockedCompareExchange と InterlockedIncremenet/InterlockedDecrement のいくつかの凝った使い方でしょうか?
私が尋ねる理由は、これがネットワーク ドライバーのデータ パスにあり、ロックを持たないことを本当に望んでいるからです。