2 つのスレッドと 1 つの共有 C++ 11 条件変数があるとします。thread1 が notify を呼び出し、その後 thread2 が wait を呼び出すとどうなりますか? スレッド 2 は永久にブロックされますか、それともスレッド 1 による通知の呼び出しにより引き続き動作しますか?
編集:
enum bcLockOperation
{
bcLockOperation_Light = -1,
bcLockOperation_Medium = 50,
bcLockOperation_Heavy = 1
}
class BC_COREDLL_EXP bcCustomMutex
{
private:
bcCustomMutex(const bcCustomMutex&);
bcCustomMutex& operator=(const bcCustomMutex&);
protected:
bcAtomic<int> mFlag;
bcMutex mMutex;
bcConditionVariable mCond;
public:
bcCustomMutex() { bcAtomicOperation::bcAtomicInit(mFlag, 0); };
~bcCustomMutex() {};
void lock(bcLockOperation pLockOperation = bcLockOperation_Medium)
{
bcINT32 lNewLoopCount = static_cast<bcINT32>(pLockOperation);
bcINT32 lLoopCounter = 0;
bcINT32 lExpected = 0;
bcINT32 lLoopCount = bcAtomicOperation::bcAtomicLoad(mFlag, bcMemoryOrder_Relaxed);
while (true)
{
while(bcAtomicOperation::bcAtomicLoad(mFlag, bcMemoryOrder_Relaxed) != 0 && lLoopCounter != lLoopCount)
++lLoopCounter;
bcAtomicOperation::bcAtomicCompareExchangeStrong(
mFlag,
&lExpected,
lNewLoopCount,
bcMemoryOrder_Acquire,
bcMemoryOrder_Relaxed);
if(lExpected == 0)
{
return;
}
else if(lLoopCounter == lLoopCount)
{
bcLockGuard<bcMutex> lGuard(mMutex);
mCond.wait(mMutex);
}
else
{
continue;
}
}
void UnLock()
{
bcAtomicOperation::bcAtomicStore(mFlag, 0, bcMemoryOrder_Relaxed);
bcUniqueLock<bcMutex> lGuard(mMutex);
mCond.notifyOne();
}
bcBOOL TryLock()
{
};
};
現在のスレッドが実行したい操作の複雑さを表す引数を各スレッドが提供できるように、カスタム ミューテックスを作成したいと考えています。操作の複雑さが低い場合、他のスレッドはスピン ロックのようなループになりますが、操作の複雑さが中程度の場合、各スレッドは 50 回反復し、条件変数によってスリープします。操作が非常に複雑な場合、他のスレッドは直接寝ます。
ここで、スレッド 1 がこのミューテックスをロックし、スレッド 2 が loopCounter が最後に到達したために待機し、条件変数のミューテックスをロックする直前にスレッド 1 が条件変数の通知を呼び出すとします。これで、スレッド 2 は、別のスレッドがカスタム ミューテックスをロックしてから unlock を呼び出すまでスリープします。
私はマルチスレッドが初めてで、学びたいと思っています。クラスにエラーが含まれているか、完全に間違っている可能性があることはわかっていますが、この問題を修正する方法や、そのようなミューテックスを作成するための優れたアルゴリズムはありますか?