同時に実行される可能性のある 3 つのスレッドがあり、実行中のロジックを以下のように制御したいと考えています。
1)thread1、thread2、thread3は3種類の時間のかかるスレッドです。一度に1つだけ実行したいです。また、thread1 もそれ自体と排他的です。つまり、1 つの thread1 が実行されている場合、2 番目の thread1 も実行されません。
2) 現在実行中のスレッド情報 (例: どの種類のスレッドが実行されているか) を知りたい。現在どのスレッドが実行されているかを知るには (このサンプルでは、thread1 が実行されていることを知りたい)、thead1 が実行されている場合は、thread2 を実行せず、ステータスを返します。
上記に基づいて、以下のロッククラスを定義しました。
enum LOCK_TYPE{
Type_UnLock = 0,
Type_Lock_1,
Type_Lock_2,
Type_Lock_3,
};
//uCurLockType is a reference, when locked by others,
//it will store current lock type and return.
std::unique_lock<std::mutex> g_lock(g_mutex, std::defer_lock);
bool CXXXLock::Lock(LOCK_TYPE uToLockType, LOCK_TYPE& uCurLockType)
{
if(m_uLockType != LOCK_TYPE::Type_UnLock)
{
uCurLockType = m_uLockType;
return false;
}
if(g_lock.try_lock())
{
m_uLockType = uToLockType;
g_lock.unlock();
return true;
}
else
{
uCurLockType = m_uLockType;
return false;
}
}
bool CXXXLock::Unlock()
{
if(g_lock.try_lock())
{
m_uLockType = LOCK_TYPE::Type_UnLock;
g_lock.unlock();
return true;
}
else
{
return false;
}
}
thread1 proc 関数では、以下のように呼び出します。また、thread2/thread3 proc 関数と同様に、GetInstance() はシングルトンであり、一意のグローバル オブジェクトを取得します。
unsigned thread1proc(LPVOID lpParam)
{
LOCK_TYPE uToLockType = LOCK_TYPE::Type_Lock_1, uCurLockType = LOCK_TYPE::Type_UnLock;
if(false == GetInstance().Lock(uToLockType, uCurLockType))
{
//it is locked by other thead, uCurLockType means which kind of thread lock it.
//store current lock type uCurLockType and exit this thread.
return;
}
// do thread logic
GetInstanct().Unlock();
return;
}
テストした後、問題ないようですが、これが標準的な方法であるかどうかを知りたいです。コメントをお待ちしております。
------2013.8.23 CXXXLock実装を更新--------
------2031.8.36--------
混乱させる間違った関数を定義したようです。私の要件では、CXXXLock::Lock 関数ではなく CXXXXLock::GetExclusiveFlag のように見えますが、実際にはロック関数がないためです。実際のアクションを実行する前に、スレッドはこの仕様に従う必要があります。