C++实战篇(一)——自旋锁的使用

参考文章

c++之理解自旋锁

什么是自旋锁

自旋锁指的是当一个线程在获取锁的时候,如果锁已经被其他线程所获取,那么该线程就将进入一个循环,不断的去判断自身是否能够获得锁 ,直到该线程获得了锁,线程才会退出循环。

自旋锁与互斥锁一样是一个为了实现对共享资源的保护而提出的锁机制,都是为了解决对某项资源的互斥使用,它们保证了在并发过程中,该共享资源在任意一个时间端都只有一个拥有者,但是与互斥锁不同的是,自旋锁在共享资源已经被占用的情况下,该线程不会进入阻塞状态,如果自旋锁已经被其他线程所占有,此时试图调用自旋锁将进入循环状态来查看是否能不能获得该锁,而这本身也是由于两者在调度机制上有所不同所造成的。

注意: 未获取锁的线程一直没有休眠处于活跃状态,虽然它本身并不执行什么工作,但是它依旧会消耗cpu,我们称这种状态叫busy waitting

示例代码

#include <iostream>
#include <atomic>
#include <thread>

using namespace std;

class CAS
{
private:
    std::atomic<bool> flag;
public:
    CAS():flag(false){}
    CAS(const CAS&)=delete;
    CAS& operator =(const CAS&)=delete;
    
    void lock()
    {
        bool expect=false;
        while(!flag.compare_exchange_strong(expect,true)) //判断能否获得锁
        {
            expect=false;  // 失败后,再次尝试
        }
    }

    void unlock()
    {
        flag.store(false);   //解锁
    }
};

int sum=0;
CAS cas;

void fun()
{
    for(int i=0;i<10;i++)
    {
        cas.lock();
        cout<<"sum:"<<sum++<<endl;
        cas.unlock();
    }
}

int main()
{
    std::thread t1(fun);
    std::thread t2(fun);
    t1.join();
    t2.join();
    return 0;
}

编译的makefile

all: demo1

demo1: 自旋锁.cpp
	g++ -pthread 自旋锁.cpp -std=c++11 -o demo1

clean:
	rm -f demo1

输出结果:

sum:0
sum:1
sum:2
sum:3
sum:4
sum:5
sum:6
sum:7
sum:8
sum:9
sum:10
sum:11
sum:12
sum:13
sum:14
sum:15
sum:16
sum:17
sum:18
sum:19

我们可以看到并不是两个线程互相干扰,而是依次递增。当获得锁的线程还未结束时,另一个线程要进入获取锁时,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,(即expect为false,flag为true,返回false,一直进入while循环),直到获取到锁才会退出循环。当一个线程退出时,另外一个在等待的线程将会立即进入,减少线程由用户态到内核态的转换。

总结

  • 自旋锁与互斥锁都是一种共享资源保护机制
  • 自旋锁的请求者状态始终为活跃的,而互斥锁则是阻塞的
  • 自旋锁如果持有锁的时间太长,则会导致其它等待获取锁的线程耗尽CPU。
  • 自旋锁本身无法保证公平性,同时也无法保证可重入性。

结语

本篇篇章有限,简单介绍一些互斥锁的使用,在下一篇文章中我们将
以日志服务部分为例,剖析以下自旋锁在多线程程序中的使用。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落雨便归尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值