我想编写一个自定义互斥锁,这样每个线程都可以提供一个参数,该参数表示当前线程想要执行的操作的复杂性。如果操作的复杂性很低,其他线程将像自旋锁一样处于循环中,但如果操作的复杂性中等,每个线程将迭代 50 次,然后将按条件变量休眠,如果操作非常复杂,其他线程将直接去睡觉。
enum LockOperation
{
LockOperation_Light = -1,
LockOperation_Medium = 50,
LockOperation_Heavy = 1
};
class CustomMutex
{
private:
protected:
std::atomic<int> mFlag;
std::mutex mMutex;
std::condition_variable mCond;
public:
CustomMutex() { std::atomic_init(&mFlag, 0); };
~CustomMutex() {};
void lock(LockOperation pLockOperation = LockOperation_Medium)
{
int lNewLoopCount = static_cast<int>(pLockOperation);
int lLoopCounter = 0;
int lExpected = 0;
int lLoopCount = std::atomic_load_explicit(&mFlag, std::memory_order_relaxed);
while (true)
{
while(std::atomic_load_explicit(&mFlag, std::memory_order_relaxed) != 0 &&
lLoopCounter != lLoopCount)
++lLoopCounter;
std::atomic_compare_exchange_strong_explicit(
&mFlag,
&lExpected,
lNewLoopCount,
std::memory_order_acquire,
std::memory_order_relaxed);
if(lExpected == 0)
{
return;
}
else if(lLoopCounter == lLoopCount)
{
lExpected = 0;
std::unique_lock<std::mutex> lGuard(mMutex);
mCond.wait(lGuard);
}
else
{
lExpected = 0;
continue;
}
}
};
bcInline void UnLock()
{
std::atomic_store_explicit(&mFlag, 0, std::memory_order_relaxed);
std::lock_guard<std::mutex> lGuard(mMutex);
mCond.notify_one();
};
};
现在假设 thread1 锁定了这个互斥体,并且 thread2 等待由于它的 loopCounter 到达它的结尾并且在锁定条件变量的互斥体之前,thread1 调用条件变量上的通知。现在 thread2 将休眠,直到另一个线程锁定此互斥体,然后对其调用 unlock。
我是多线程新手,我想学习。我知道我的课程可能包含错误或可能完全错误,但有没有办法纠正这个问题或编写这样一个互斥锁的好算法。
另一个问题:我的原子操作顺序正确吗?
(对不起,如果我的问题有点模棱两可,我的英语不好)