当前位置: 首页 > news >正文

多线程 - 自旋锁

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

多线程 - 自旋锁

收录于专栏[Linux学习]
本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

概述

原理 

优点与缺点 

优点

缺点 

使用场景 

自旋锁伪代码实现

Linux 提供的自旋锁系统调用

注意事项

结论 

案例代码 


概述

自旋锁是一种多线程同步机制,用于保护共享资源免受并发访问的影响。在多个线程尝试获取锁时,它们会持续自旋(即在一个循环中不断检查锁是否可用)而不是立即进入休眠状态等待锁的释放。这种机制减少了线程切换的开销,适用于短时间内锁的竞争情况,但是不合理的使用,可能会造成 CPU 的浪费。 

原理 

自旋锁通常使用一个共享的标志位(如一个布尔值)来表示锁的状态。当标志位为 true 时,表示锁已被某个线程占用;当标志位为 false 时,表示锁可用。当一个线程尝试获取自旋锁时,它会不断检查标志位:

1. 如果标志位为 false,表示锁可用,线程将设置标志位为 true,表示自己占用了锁,并进入临界区。

2. 如果标志位为 true(即锁已被其他线程占用),线程会在一个循环中不断自旋等待,直到锁被释放。 

优点与缺点 

优点

1. 低延迟:自旋锁使用于短时间内的锁竞争情况,因为它不会让线程进入休眠状态,从而避免了线程转换的开销,提高了操作系统的效率。

2. 减少了系统调度开销: 当多个线程同时自旋等待同一个锁时,如果没有适当的退避策略,可能会导致所有线程都在不断检查锁状态而无法进入临界区,形成活锁。

缺点 

1. CPU 资源浪费:如果锁的持有时间较长,等待获取锁的线程会一直循环等待,导致 CPU 资源的浪费。

2. 可能引起活锁:当多个线程同时自旋等待同一个锁时,如果没有适当的退避策略,可能会导致所有线程都在不断地检查锁状态而无法进入临界区,形成活锁。 

使用场景 

1. 短暂等待地情况:使用于锁被占用时间很短地场景,如多线程对共享数据进行简单的读写操作。

2. 多线程的使用:通常用于系统底层,同步多个 CPU 对共享资源的访问。 

自旋锁伪代码实现

自旋锁的实现通常使用原子操作来保证操作的原子性,常用的软件实现方式是通过 CAS(Compare-And-Swap)指令实现。以下是一个简单的自旋锁实现示例(伪代码):

#include <stdio.h>
#include <stdatomic.h>
#include <pthread.h>
#include <unistd.h>
// 使用原子标志来模拟自旋锁
atomic_flag spinlock = ATOMIC_FLAG_INIT; // ATOMIC_FLAG_INIT 是0
// 尝试获取锁
void spinlock_lock()
{while (atomic_flag_test_and_set(&spinlock)){// 如果锁被占用,则忙等待}
}
// 释放锁
void spinlock_unlock()
{atomic_flag_clear(&spinlock);
}
typedef _Atomic struct
{
#if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1_Bool __val;
#elseunsigned char __val;
#endif
} atomic_flag;

功能描述:

atomic_flag_test_and_set 函数检查 atomic_flag 的当前状态。如果 atomic_flag 之前没有被设置过(即其值为 false 或 未设置 状态),则函数会将其设置为 true(或 设置 状态),并返回先前的值(在这种情况下为 false)。如果 atomic_flag 之前已经被设置过(即其值为 true),则函数不会改变其状态,但会返回 true。


原子性:

这个操作是原子的,意味着在多线程环境中,它保证了对 atomic_flag 的读取和修改是不可分割的。当一个线程调用此函数时,其他线程无法看到这个操作的任何中间状态,这确保了操作的安全性。

Linux 提供的自旋锁系统调用

#include <pthread.h>
int pthread_spin_lock(pthread_spinlock_t *lock);
int pthread_spin_trylock(pthread_spinlock_t *lock);
int pthread_spin_unlock(pthread_spinlock_t *lock);
int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
int pthread_spin_destroy(pthread_spinlock_t *lock);

注意事项

1. 在使用自旋锁时,需要确保锁被释放的时间尽可能短,以避免 CPU 资源的浪费。

2. 在多 CPU 环境下,自旋锁可能不如其他锁机制高效,因为它可能导致线程在不同的 CPU 上自旋等待。

结论 

自旋锁是一种适用于短时间内竞争情况的同步机制,它通过减少线程切换的开销来提高锁操作的效率。然而,它存在 CPU 资源浪费和可能引起活锁等缺点。在使用自旋锁时,需要根据具体的应用场景进行选择,并确保锁被释放的时间尽可能短。 

案例代码 

// 操作共享变量会有问题的售票系统代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>int ticket = 1000;
pthread_spinlock_t lock;void *route(void *arg)
{char *id = (char *)arg;while (1){pthread_spin_lock(&lock);if (ticket > 0){usleep(1000);printf("%s sells ticket:%d\n", id, ticket);ticket--;pthread_spin_unlock(&lock);}else{pthread_spin_unlock(&lock);break;}}return nullptr;
}int main(void)
{pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE);pthread_t t1, t2, t3, t4;pthread_create(&t1, NULL, route, (void *)"thread 1");pthread_create(&t2, NULL, route, (void *)"thread 2");pthread_create(&t3, NULL, route, (void *)"thread 3");pthread_create(&t4, NULL, route, (void *)"thread 4");pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_join(t3, NULL);pthread_join(t4, NULL);pthread_spin_destroy(&lock);return 0;
}

相关文章:

多线程 - 自旋锁

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 多线程 - 自旋锁 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 概述 原理 优点与…...

vue2 - Day02 -计算属性(computed)、侦听器(watch)和方法(methods)

在 Vue.js 中&#xff0c;计算属性&#xff08;computed&#xff09;、侦听器&#xff08;watch&#xff09;和方法&#xff08;methods&#xff09;都是响应式的数据处理方式 文章目录 1. 方法&#xff08;Methods&#xff09;1.1. 是什么1.2. 怎么用示例&#xff1a; 1.3. 特…...

Linux C 程序 【05】异步写文件

1.开发背景 Linux 系统提供了各种外设的控制方式&#xff0c;其中包括文件的读写&#xff0c;存储文件的介质可以是 SSD 固态硬盘或者是 EMMC 等。 其中常用的写文件方式是同步写操作&#xff0c;但是如果是写大文件会对 CPU 造成比较大的负荷&#xff0c;采用异步写的方式比较…...

Liveweb视频汇聚平台支持WebRTC协议赋能H.265视频流畅传输

随着科技的飞速发展和网络技术的不断革新&#xff0c;视频监控已经广泛应用于社会各个领域&#xff0c;成为现代安全管理的重要组成部分。在视频监控领域&#xff0c;视频编码技术的选择尤为重要&#xff0c;它不仅关系到视频的质量&#xff0c;还直接影响到视频的传输效率和兼…...

SQL组合查询

本文讲述如何利用 UNION 操作符将多条 SELECT 语句组合成一个结果集。 1. 组合查询 多数 SQL 查询只包含从一个或多个表中返回数据的单条 SELECT 语句。但是&#xff0c;SQL 也允许执行多个查询&#xff08;多条 SELECT 语句&#xff09;&#xff0c;并将结果作为一个查询结果…...

方正畅享全媒体新闻采编系统 screen.do SQL注入漏洞复现

0x01 产品简介 方正畅享全媒体新闻生产系统是以内容资产为核心的智能化融合媒体业务平台,融合了报、网、端、微、自媒体分发平台等全渠道内容。该平台由协调指挥调度、数据资源聚合、融合生产、全渠道发布、智能传播分析、融合考核等多个平台组成,贯穿新闻生产策、采、编、发…...

【机器学习】【集成学习——决策树、随机森林】从零起步:掌握决策树、随机森林与GBDT的机器学习之旅

这里写目录标题 一、引言机器学习中集成学习的重要性 二、决策树 (Decision Tree)2.1 基本概念2.2 组成元素2.3 工作原理分裂准则 2.4 决策树的构建过程2.5 决策树的优缺点&#xff08;1&#xff09;决策树的优点&#xff08;2&#xff09;决策树的缺点&#xff08;3&#xff0…...

Flink执行模式(批和流)如何选择

DataStream API支持不同的运行时执行模式(batch/streaming),你可以根据自己的需求选择对应模式。 DataStream API的默认执行模式就是streaming,用于需要连续增量处理并且预计会一直保持在线的无界(数据源输入是无限的)作业。 而batch执行模式则用于有界(输入有限)作业…...

LeetCode:101. 对称二叉树

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输…...

LDO输入电压不满足最小压差时输出会怎样?

1、LDO最小压差 定义&#xff1a;低压差稳压器&#xff08;Low-dropout regulator&#xff0c;LDO&#xff09;LDO的最小压差Vdo指的是LDO正常工作时&#xff0c;LDO的输入电压必须高于LDO输出电压的差值&#xff0c;即Vin≥VdoVout   Vdo的值不是定值&#xff0c;会随着负载…...

源码分析之Openlayers中ZoomSlider滑块缩放控件

概述 ZoomSlider滑块缩放控件就是Zoom缩放控件的异形体&#xff0c;通过滑块的拖动或者点击滑槽&#xff0c;实现地图的缩放&#xff1b;另外其他方式控制地图缩放时&#xff0c;也会引起滑块在滑槽中的位置改变&#xff1b;即ZoomSlider滑块缩放控件会监听地图的缩放级别&…...

在Win11系统上安装Android Studio

诸神缄默不语-个人CSDN博文目录 下载地址&#xff1a;https://developer.android.google.cn/studio?hlzh-cn 官方安装教程&#xff1a;https://developer.android.google.cn/studio/install?hlzh-cn 点击Next&#xff0c;默认会同时安装Android Studio和Android虚拟机&#…...

华为ensp--BGP路径选择-AS_Path

学习新思想&#xff0c;争做新青年&#xff0c;今天学习的是BGP路径选择-AS_Path 实验目的: 理解AS_Path属性的概念 理解通过AS_Path属性进行选路的机制 掌握修改AS_Path属性的方法 实验内容: 本实验模拟了一个运营商网络场景&#xff0c;所有路由器都运行BGP协议&#xff…...

Android Java Ubuntu系统如何编译出 libopencv_java4.so

Cmake: cd ~ wget https://github.com/Kitware/CMake/releases/download/v3.30.3/cmake-3.30.3-linux-x86_64.tar.gztar -xzvf cmake-3.30.3-linux-x86_64.tar.gz sudo ln -sf $(pwd)/cmake-3.30.3-linux-x86_64/bin/* /usr/bin/cmake --versionAndroid NDK: wget https://…...

WPF Binding 绑定

绑定是 wpf 开发中的精髓&#xff0c;有绑定才有所谓的数据驱动。 1 . 背景 目前 wpf 界面可视化的控件&#xff0c;继承关系如下&#xff0c; 控件的数据绑定&#xff0c;基本上都要借助于 FrameworkElement 的 DataContext 属性。 只有先设置了控件的 DataContext 属性&…...

算法笔记—前缀和(动态规划)

【模板】前缀和_牛客题霸_牛客网 (nowcoder.com) #include <initializer_list> #include <iostream> #include <vector> using namespace std;int main() {//输入数据int n,q;cin>>n>>q;vector<int> arr;arr.resize(n1);for(int i1;i<…...

将HTML转换为PDF:使用Spire.Doc的详细指南(二)无水印版

目录 引言 一、准备工作 1. 下载Spire.Doc for Java破解版 2. 将JAR包安装到本地Maven (1) 打开命令提示符 (2) 输入安装命令 (3) 在pom.xml中导入依赖 二、实现HTML到PDF的转换 1. 创建Java类 2. 完整代码示例 3. 代码解析 4. 处理图像 5. 性能优化 6. 错误处理…...

V900新功能-电脑不在旁边,通过手机给PLC远程调试网关配置WIFI联网

您使用BDZL-V900时&#xff0c;是否遇到过以下这种问题&#xff1f; 去现场配置WIFI发现没带电脑&#xff0c;无法联网❌ 首次配置WIFI时需使用网线连电脑&#xff0c;不够快捷❌ 而博达智联为解决该类问题&#xff0c;专研了一款网关配网工具&#xff0c;实现用户现场使用手机…...

prober.php探针

raw.githubusercontent.com/kmvan/x-prober/master/dist/prober.php...

esp8266_TFTST7735语音识别UI界面虚拟小助手

文章目录 一 实现思路1 项目简介1.1 项目效果1.2 实现方式 2 项目构成2.1 软硬件环境2.2 完整流程总结&#xff08;重点整合&#xff09;(1) 功能逻辑图(2) 接线(3) 使用esp8266控制TFT屏(4)TFT_espI库配置方法(5) TFT_esp库常用代码详解(6)TFT屏显示图片(7) TFT屏显示汉字(8) …...

YOLO X Layout实战:商业报告智能解析,快速提取表格与图表数据

YOLO X Layout实战&#xff1a;商业报告智能解析&#xff0c;快速提取表格与图表数据 1. 商业文档处理的痛点与解决方案 在金融分析、市场研究等专业领域&#xff0c;我们经常需要处理大量商业报告。这些PDF或扫描件文档中包含大量有价值的数据表格和图表&#xff0c;但手动提…...

Keil软件仿真中STM32F407卡在HSE就绪问题的Debugconfig.ini配置指南

1. 为什么STM32F407软件仿真会卡在HSE就绪&#xff1f; 最近在用Keil MDK调试STM32F407项目时&#xff0c;发现一个奇怪现象&#xff1a;软件仿真总是卡在"Wait till HSE is ready"这个地方&#xff0c;死活进不了main函数。这个问题困扰了我整整两天&#xff0c;最后…...

双轨制新零售系统模式开发解析

双轨制新零售系统模式开发解析&#xff1a;从架构设计到合规落地在新零售数字化转型浪潮中&#xff0c;双轨制模式凭借其轻量化组织架构与高效裂变能力&#xff0c;成为企业低成本获客与业绩增长的重要工具。不同于传统多级分销的复杂层级&#xff0c;双轨制通过“二二复制”的…...

红日靶场(二)phpstudy服务异常排查与修复指南

1. phpstudy服务异常排查思路 遇到phpstudy服务启动失败时&#xff0c;很多新手会直接重装软件&#xff0c;其实80%的问题通过系统化排查都能解决。我处理过上百个红日靶场环境&#xff0c;总结出这套黄金排查法则&#xff1a; 首先确认报错类型&#xff0c;常见的三种情况&…...

RPCS3终极指南:在电脑上完美运行PS3游戏的完整教程

RPCS3终极指南&#xff1a;在电脑上完美运行PS3游戏的完整教程 【免费下载链接】rpcs3 PS3 emulator/debugger 项目地址: https://gitcode.com/GitHub_Trending/rp/rpcs3 还在为无法重温经典PS3游戏而烦恼吗&#xff1f;RPCS3作为全球领先的免费开源PlayStation 3模拟器…...

Tendis水平扩展实战:在线数据迁移与节点扩容最佳实践

Tendis水平扩展实战&#xff1a;在线数据迁移与节点扩容最佳实践 【免费下载链接】Tendis Tendis is a high-performance distributed storage system fully compatible with the Redis protocol. 项目地址: https://gitcode.com/gh_mirrors/te/Tendis Tendis作为腾讯开…...

如何通过Odoo合同自动化与电子签名实现企业文档管理数字化转型

如何通过Odoo合同自动化与电子签名实现企业文档管理数字化转型 【免费下载链接】odoo Odoo. Open Source Apps To Grow Your Business. 项目地址: https://gitcode.com/GitHub_Trending/od/odoo 企业在合同管理过程中常面临效率低下、合规风险高、协作成本大等挑战。传统…...

C#安装步骤以及流程易出错提醒修正

C# 开发环境安装步骤 Visual Studio 安装 从 Microsoft 官网 下载 Visual Studio Community&#xff08;免费版本&#xff09;。运行安装程序&#xff0c;选择“使用 C# 的桌面开发”工作负载&#xff0c;确保勾选 .NET SDK 和核心组件。 验证安装 打开命令提示符或 PowerShe…...

告别手动复制粘贴:MeterSphere参数提取功能详解,让你的接口自动化测试效率翻倍

MeterSphere参数提取实战&#xff1a;构建动态接口测试链的三大高阶技巧 在持续集成环境中&#xff0c;接口自动化测试往往面临一个关键挑战&#xff1a;如何让不同接口之间实现数据动态传递&#xff1f;传统的手动复制粘贴不仅效率低下&#xff0c;更难以应对复杂业务场景。Me…...

OpenClaw硬件控制实验:ollama-QwQ-32B通过串口操控智能家居

OpenClaw硬件控制实验&#xff1a;ollama-QwQ-32B通过串口操控智能家居 1. 为什么选择OpenClaw做硬件控制 去年冬天的一个深夜&#xff0c;我被空调定时关闭后冻醒的经历&#xff0c;让我开始思考如何让AI真正理解物理世界。传统智能家居App的固定场景模式已经不能满足我的需…...