本帖最后由 wushaominkk 于 2023-12-1 09:17 编辑
[C++] 纯文本查看 复制代码 [i]/************************************************************************
[/i][i]SpinLockTAS<> sp_lock;
[/i][i]std::unique_lock<SpinLockTAS<>> lk(sp_lock);
[/i][i]功 能:[/i][i] TAS[/i][i]自旋锁[/i][i]
[/i][i]返回值:[/i][i]void
[/i][i]************************************************************************/
[/i]template<::std::size_t sleepWhenLockFailedInMicroSecond = ::std::size_t(-1)>
class SpinLockTAS
{
public:
void lock();
void unlock();
private:
::std::atomic_flag locked_flag = ATOMIC_FLAG_INIT;
};
[i]/************************************************************************
[/i][i]SpinLockCAS<> sp_lock;
[/i][i]std::unique_lock<SpinLockCAS<>> lk(sp_lock);
[/i][i]功 能:[/i][i] CAS[/i][i]自旋锁[/i][i]
[/i][i]************************************************************************/
[/i]template<::std::size_t sleepWhenLockFailedInMicroSecond = ::std::size_t(-1)>
class SpinLockCAS
{
public:
void lock();
void unlock();
private:
::std::atomic<bool> locked_flag;
};
template<::std::size_t sleepWhenLockFailedInMicroSecond>
void SpinLockTAS<sleepWhenLockFailedInMicroSecond>::lock()
{
while (this->locked_flag.test_and_set())
{
if (sleepWhenLockFailedInMicroSecond <= ::std::size_t(0))
::std::this_thread::yield();
else if (sleepWhenLockFailedInMicroSecond > 0)
::std::this_thread::sleep_for(::std::chrono::microseconds(sleepWhenLockFailedInMicroSecond));
}
}
template<::std::size_t sleepWhenLockFailedInMicroSecond>
void SpinLockTAS<sleepWhenLockFailedInMicroSecond>::unlock()
{
this->locked_flag.clear();
}
template<::std::size_t sleepWhenLockFailedInMicroSecond>
void SpinLockCAS<sleepWhenLockFailedInMicroSecond>::lock()
{
bool expect = false;
while (!this->locked_flag.compare_exchange_weak(expect, true))
{
expect = false;
if (sleepWhenLockFailedInMicroSecond <= ::std::size_t(0))
::std::this_thread::yield();
else if (sleepWhenLockFailedInMicroSecond > 0)
::std::this_thread::sleep_for(::std::chrono::microseconds(sleepWhenLockFailedInMicroSecond));
}
}
template<::std::size_t sleepWhenLockFailedInMicroSecond>
void SpinLockCAS<sleepWhenLockFailedInMicroSecond>::unlock()
{
this->locked_flag.store(false);
} |