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

news/2024/9/23 11:20:05/

参考文章

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: demo1demo1: 自旋锁.cppg++ -pthread 自旋锁.cpp -std=c++11 -o demo1clean: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。
  • 自旋锁本身无法保证公平性,同时也无法保证可重入性。

结语

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


http://www.ppmy.cn/news/1430101.html

相关文章

做事要留有余地

《韩非子》里有一个著名的故事&#xff0c;叫盆水杀人。 春秋战国年间&#xff0c;齐国国君有一个好朋友叫夷射&#xff0c;一年冬天&#xff0c;齐王叫夷射到宫里喝酒&#xff0c;二人对饮&#xff0c;你一杯我一杯&#xff0c;一杯又一杯&#xff0c;喝的是前仰后合&#xf…

c++在visual studio上的默认配置

右键 新建项 右键源文件 属性

MLP/CNN/RNN/Transformer主流深度学习模型的区别

1. 多层感知机&#xff08;MLP&#xff09; 核心特征&#xff1a; 结构&#xff1a;MLP 是一种基本的前馈神经网络&#xff0c;包含一个输入层、一个或多个隐藏层以及一个输出层。每层由全连接的神经元组成。用途&#xff1a;适用于简单的分类和回归任务。限制&#xff1a;不…

【SAP ME 18】SAP ME创建开发组件ear

1、说明 SC开发组件ear项目是所有sap me二次开发项目的编译入和部署入口,通过ear可以有效的针对子项目的编译和部署 2、创建开发组件

书生·浦语大模型全链路开源体系-第5课

书生浦语大模型全链路开源体系-第5课 书生浦语大模型全链路开源体系-第5课相关资源LMDeploy基础配置LMDeploy运行环境下载internlm2-chat-1_8b模型使用Transformer来直接运行InternLM2-Chat-1.8B模型使用LMDeploy以命令行方式与InternLM2-Chat-1.8B模型对话设置KV Cache最大占用…

kerberos:介绍

文章目录 一、介绍二、kerberos框架1、名词解释2、框架 三、优缺点四、其他认证机制1、SSL2、OAuth3、LDAP 一、介绍 Kerberos是一种计算机网络授权协议&#xff0c;主要用于在非安全网络环境中对个人通信进行安全的身份认证。这个协议由麻省理工学院&#xff08;MIT&#xff…

K8s: 关于Kubernetes中的Pod的创建,实现原理,Job调度pod以及pod网络

Pod 概述 Pod 是最小部署的单元&#xff0c;Pod里面是由一个或多个容器组成&#xff0c;也就是一组容器的集合一个pod中的容器是共享网络命名空间&#xff0c;每个Pod包含一个或多个紧密相关的用户业务容器Pod 是 k8s 系统中可以创建和管理的最小单元是资源对象模型中由用户创…

python 学习笔记(零散版)

array&#xff08;数组&#xff09;: 是numpy里的数据类型&#xff0c;用于存放同类型的多个元素&#xff0c;可以是多维的&#xff0c;内存连续&#xff0c;可以用索引访问数组中的元素。 以下是创建不同类型array的实例&#xff1a; import numpy as np# 整数类型 arr_int…