C++ 并发专题 - 自旋锁的实现(Spinlock)

一:概述

        自旋锁(Spinlock) 是一种用于线程同步的锁,它通过让线程不断地自我检查("自旋")来判断是否可以获得锁,而不是让线程在等待时进入阻塞状态。这种方式使得线程能够在锁被释放之前反复检查锁的状态,从而快速尝试获取锁,而不需要进行上下文切换。

二:工作原理:

  1. 线程在尝试获取自旋锁时,如果发现锁没有被占用(即锁处于“空闲”状态),它会获取锁并继续执行。
  2. 如果锁已经被其他线程占用(即锁处于“忙碌”状态),线程不会被阻塞,而是进入一个不断检查锁状态的循环,直到锁被释放。
  3. 一旦锁被释放,线程立即获得锁并继续执行。

三:优缺点

      优点:
  1. 避免上下文切换:与传统的锁(如互斥锁)不同,自旋锁不让线程进入阻塞状态。当锁已经被占用时,线程不会进入操作系统的调度队列,而是不断自旋,消除了线程上下文切换的开销。
  2. 适用于锁持有时间较短的情况:如果锁的持有时间很短,自旋锁可以比其他类型的锁更加高效,因为自旋等待的开销较小。
      缺点:
  1. 忙等待导致资源浪费:如果多个线程频繁竞争锁,并且锁持有时间较长,那么自旋锁会导致CPU资源的浪费,因为线程会不断检查锁的状态,消耗了大量计算资源而没有实际的进展。
  2. 可能会导致活锁:如果线程在竞争自旋锁时总是处于自旋状态,可能会导致线程无法获得锁,造成活锁(即系统不断尝试某个操作,但始终无法成功)。
  3. 不适用于高负载的情况:在高并发的环境下,自旋锁可能会造成性能下降,因为自旋时的CPU消耗可能会比阻塞等待的成本还要高。

四:适用场景:

  • 自旋锁通常适用于锁的持有时间非常短的场景。比如多核处理器上,当线程需要进行简单的原子操作时,自旋锁能够避免由于线程上下文切换带来的性能损失。
  • 适用于竞争不激烈、获取锁的等待时间较短的场景。比如:一些微小的资源访问,锁定时间在纳秒到微秒级别的操作。

五:代码

#include <atomic>
#include <thread>class Spinlock{//初始化一个原子布尔类型变量  std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:void lock(){/*flag.test_and_set是一个原子操作, 它会检查 flag 的值并将其设置为 true。如果原本是 false, 它就设置为true,并返回false,否则返回 true。当 flag 被设置为 true 时,表示锁被占用,此时会不断循环直到 flag 被清除。std::memory_order_acq_rel 是一个内存顺序, 它保证lock操作之前的读写操作(例如访问共享资源)会在此锁的获取之前完成,并且在解锁时,锁后的操作会被其他线程看到。 */while( flag.test_and_set(std::memory_order_acq_rel) );}void unlock(){//释放锁的原子操作,清除atomic_flag, 将其设置为 false,其他线程就可以获得锁//std::memory_order_relase 保证了释放锁时,前面的操作会在此锁释放前可见。 flag.clear(std::memory_order_release);}};Spinlock spin;void workOnResource(){spin.lock();std::this_thread::sleep_for(std::chrono::milliseconds(2000));spin.unlock();
}int main(){std::thread t(workOnResource);std::thread t2(workOnResource);t.join();t2.join();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/471139.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

专题十八_动态规划_斐波那契数列模型_路径问题_算法专题详细总结

目录 动态规划 动态规范五步走&#xff1a; 1. 第 N 个泰波那契数&#xff08;easy&#xff09; 解析&#xff1a; 1.状态表达式&#xff1a; 2.状态转移方程&#xff1a; 3.初始化&#xff1a; 4.填表顺序&#xff1a; 5.返回值 编写代码&#xff1a; 总结&#xff…

阿里云centos7.9服务器磁盘挂载,切换服务路径

项目背景 1、项目使用的服务器为阿里云centos7.9&#xff0c;默认的磁盘为vda&#xff0c;文件系统挂载在这个磁盘上&#xff0c;项目上使用的文件夹为/home/hnst/uploadPath 2、vda使用率已达到91% 3、现购置一块新的磁盘为vdb&#xff0c;大小为2T 目的 切换服务所使用的…

STM32问题集

这里写目录标题 一、烧录1、 Can not connect to target!【ST-LINK烧录】 一、烧录 1、 Can not connect to target!【ST-LINK烧录】 烧录突然 If the target is in low power mode, please enable “Debug in Low Power mode” option from Target->settings menu 然后就&…

Scala学习记录,case class,迭代器

case class case class创建的对象的属性是不可改的 创建对象&#xff0c;可以不用写new 自动重写&#xff1a;toString, equals, hashCode, copy 自动重写方法&#xff1a;toString,equals,hashCode,copy 小习一下 1.case class 的定义语法是什么 基本形式&#xff1a;case …

成都睿明智科技有限公司解锁抖音电商新玩法

在这个短视频风起云涌的时代&#xff0c;抖音电商以其独特的魅力迅速崛起&#xff0c;成为众多商家争夺的流量高地。而在这片充满机遇与挑战的蓝海中&#xff0c;成都睿明智科技有限公司犹如一颗璀璨的新星&#xff0c;以其专业的抖音电商服务&#xff0c;助力无数品牌实现从零…

阅读2020-2023年《国外军用无人机装备技术发展综述》笔记_技术趋势

目录 文献基本信息 序言 1 发展概况 2 重点技术发展 2.1 人工智能技术 2.1.1 应用深化 2.1.2 作战效能提升 2.2 航空技术 2.2.1螺旋桨设计创新 2.2.2 发射回收技术进步 2.3 其他相关技术 2.3.1 远程控制技术探 2.3.2 云地控制平台应用 3 装备系统进展 3.1 无人作…

LeetCode 86.分隔链表

题目&#xff1a; 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 思路&#xff1a; 代码&#xff1a; /*** Definiti…

SystemVerilog学习笔记(六):控制流

条件语句 条件语句用于检查块中的语句是否被执行。条件语句创建语句块。如果给出的表达式是 true&#xff0c;执行块中的语句集&#xff0c;如果表达式为 false&#xff0c;则 else 块语句将最后执行。 序号条件语句1.if2.if-else3.if-else ladder4.unique if5.unique0 if6.p…

SQL,力扣题目1127, 用户购买平台

一、力扣链接 LeetCode_1127 二、题目描述 支出表: Spending ---------------------- | Column Name | Type | ---------------------- | user_id | int | | spend_date | date | | platform | enum | | amount | int | ------------------…

【计算机网络】【传输层】【习题】

计算机网络-传输层-习题 文章目录 10. 图 5-29 给出了 TCP 连接建立的三次握手与连接释放的四次握手过程。根据 TCP 协议的工作原理&#xff0c;请填写图 5-29 中 ①~⑧ 位置的序号值。答案技巧 注&#xff1a;本文基于《计算机网络》&#xff08;第5版&#xff09;吴功宜、吴英…

群控系统服务端开发模式-应用开发-前端个人信息功能

个人信息功能我把他分为了3部分&#xff1a;第一部分是展示登录者信息&#xff1b;第二步就是登录者登录退出信息&#xff1b;第三部分就是修改个人资料。 一、展示登录者信息 1、优先添加固定路由 在根目录下src文件夹下route文件夹下index.js文件中&#xff0c;添加如下代码 …

Qwen2-VL:发票数据提取、视频聊天和使用 PDF 的多模态 RAG 的实践指南

概述 随着人工智能技术的迅猛发展&#xff0c;多模态模型在各类应用场景中展现出强大的潜力和广泛的适用性。Qwen2-VL 作为最新一代的多模态大模型&#xff0c;融合了视觉与语言处理能力&#xff0c;旨在提升复杂任务的执行效率和准确性。本指南聚焦于 Qwen2-VL 在三个关键领域…

Java面向对象高级2

1.代码块 2.内部类 成员内部类 public class Demo{public static void main(String[] args) {outer.inner innew outer().new inner();in.run();}}class outer{private String str"outer";public class inner{public void run(){String sstr;System.out.println(s);…

Elasticsearch 8.16:适用于生产的混合对话搜索和创新的向量数据量化,其性能优于乘积量化 (PQ)

作者&#xff1a;来自 Elastic Ranjana Devaji, Dana Juratoni Elasticsearch 8.16 引入了 BBQ&#xff08;Better Binary Quantization - 更好的二进制量化&#xff09;—— 一种压缩向量化数据的创新方法&#xff0c;其性能优于传统方法&#xff0c;例如乘积量化 (Product Qu…

androidstudio下载gradle慢

1&#xff0c;现象&#xff1a; 2&#xff0c;原因&#xff0c;国内到国外网址慢 3&#xff0c;解决方法&#xff1a;更改gradle-wrapper.properties #Wed Sep 26 20:01:52 CST 2018 distributionBaseGRADLE_USER_HOME distributionPathwrapper/dists zipStoreBaseGRADLE_USER…

浅谈:基于三维场景的视频融合方法

视频融合技术的出现可以追溯到 1996 年 , Paul Debevec等 提出了与视点相关的纹理混合方法 。 也就是说 &#xff0c; 现实的漫游效果不是从摄像机的角度来看 &#xff0c; 但其仍然存在很多困难 。基于三维场景的视频融合 &#xff0c; 因其直观等特效在视频监控等相关领域有着…

探索Python的HTTP利器:Requests库的神秘面纱

文章目录 **探索Python的HTTP利器&#xff1a;Requests库的神秘面纱**一、背景&#xff1a;为何选择Requests库&#xff1f;二、Requests库是什么&#xff1f;三、如何安装Requests库&#xff1f;四、Requests库的五个简单函数使用方法1. GET请求2. POST请求3. PUT请求4. DELET…

【算法一周目】双指针(2)

目录 有效三角形的个数 解题思路 C代码实现 和为s的两个数字 解题思路 C代码实现 三数之和 解题思路 C代码实现 四数之和 解题思路 C代码实现 有效三角形的个数 题目链接&#xff1a;611. 有效三角形的个数题目描述&#xff1a;给定一个包含非负整数的数组nums&…

基于Python的网上银行综合管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

C++编程技巧与规范-类和对象

类和对象 1. 静态对象的探讨与全局对象的构造顺序 静态对象的探讨 类中的静态成员变量(类类型静态成员) 类中静态变量的声明与定义&#xff08;类中声明类外定义&#xff09; #include<iostream> using namespace std;namespace _nmspl {class A{public:A():m_i(5){…