大神论坛

找回密码
快速注册
查看: 195 | 回复: 0

[源码] 用C++封装自旋锁 利用C++11及其以上标准封装自旋锁

主题

帖子

0

积分

初入江湖

UID
653
积分
0
精华
威望
0 点
违规
大神币
68 枚
注册时间
2023-10-14 10:44
发表于 2023-12-02 09:02
本帖最后由 ahxhs 于 2023-12-02 09:02 编辑

用C++封装自旋锁 利用C++11及其以上标准封装自旋锁

[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);
}


注:若转载请注明大神论坛来源(本贴地址)与作者信息。

返回顶部