【在Linux世界中追寻伟大的One Piece】自旋锁
目录
1 -> 概述
2 -> 原理
3 -> 优缺点及使用场景
3.1 -> 优点
3.2 -> 缺点
3.3 -> 使用场景
4 -> 纯软件自旋锁类似的原理实现
4.1 -> 结论
5 -> 样例代码

1 -> 概述
自旋锁是一种多线程同步机制,用于保护共享资源避免受并发访问的影响。
在多个线程尝试获取锁时,它们会持续自选(即在一个循环中不断检查锁是否可用)而不是立即进入休眠状态等待锁的释放。
这种机制减少了线程切换的开销,适用于短时间内锁的竞争情况。但是不合理的使用,可能会造成CPU的浪费。
2 -> 原理
自旋锁通常使用一个共享的标志位(如一个布尔值)来表示锁的状态。当标志位为true时,表示锁已经被某个线程占用;当标志位为false时,表示锁可用。当一个线程尝试获取自旋锁时,它会不断检查标志位:
- 如果标志位为true(即锁已经被其他线程占用),线程会在一个循环中不断自旋等待,直到锁被释放。
- 如果标志位为false,表示锁可用,线程将标志位设置为true,表示自己占用了锁,并进入临界区。
大致流程:
- 尝试获取锁:当一个线程需要访问共享资源时,它会尝试获取自旋锁。如果锁已经被其他线程持有,则当前线程不会立即进入阻塞状态。
- 自旋等待:当前线程会进入一个循环(通常称为“自旋”),在这个循环中它会不断检查锁是否已经被释放。这通常是通过一个原子操作(如CAS,Compare-And-Swap)来实现的,该操作会检查锁的状态并尝试将其设置为已锁定。
- 获取锁成功:如果锁已经被释放(即其他线程已经完成了对共享资源的访问并释放了锁),则当前线程会成功获取锁,并退出自旋循环。
- 执行临界区代码:一旦获取了锁,当前线程就可以安全地访问共享资源,并执行临界区代码。
- 释放锁:完成临界区代码的执行后,当前线程会释放锁,以便其他线程可以获取锁并访问共享资源。
3 -> 优缺点及使用场景
3.1 -> 优点
- 低延迟:自旋锁适用于短时间内的锁竞争情况。因为它不会让线程进入休眠状态,从而避免了线程切换的开销,提高了锁的操作效率。
- 减少系统调度开销:等待锁的线程不会被阻塞,不需要上下文切换,从而减少了系统调度开销。
3.2 -> 缺点
- CPU资源浪费:如果锁的持有时间较长,等待获取锁的线程就会一直循环等待,导致CPU资源的浪费。
- 可能引起活锁:当多个线程同时自旋等待同一个锁时,如果没有适当的退避策略,可能会导致所有线程都在不断检查锁状态而无法进入临界区,形成活锁。
3.3 -> 使用场景
- 短暂等待的情况:适用于锁被占用时间很短的场景,如多线程对共享数据进行简单的读写操作。
- 多线程锁使用:通常用于系统底层,同步多个CPU对共享资源的访问。
4 -> 纯软件自旋锁类似的原理实现
自旋锁的实现通常使用原子操作来保证操作的原子性,常用的软件实现方式是通过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);
注意:
- 在使用自旋锁时,需要确保锁被释放的时间尽可能短,以避免CPU资源的浪费。
- 在多CPU环境下,自旋锁可能不如其他锁机制高效,因为它可能导致线程在不同的CPU上自旋等待。
4.1 -> 结论
自旋锁是一种适用于短时间内锁竞争情况的同步机制,它通过减少线程切换的开销来提高锁操作的效率。然而,它也存在CPU资源浪费和可能引起活锁等缺点。在使用自旋锁时,需要根据具体的应用场景进行选择,并确保锁被释放的时间尽可能短。
5 -> 样例代码
// 操作共享变量会有问题的售票系统代码#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);
}
感谢各位大佬支持!!!
互三啦!!!
相关文章:
【在Linux世界中追寻伟大的One Piece】自旋锁
目录 1 -> 概述 2 -> 原理 3 -> 优缺点及使用场景 3.1 -> 优点 3.2 -> 缺点 3.3 -> 使用场景 4 -> 纯软件自旋锁类似的原理实现 4.1 -> 结论 5 -> 样例代码 1 -> 概述 自旋锁是一种多线程同步机制,用于保护共享资源避免受并…...
前端编辑器JSON HTML等,vue2-ace-editor,vue3-ace-editor
与框架无关 vue2-ace-editor有问题,ace拿不到(brace) 一些组件都是基于ace-builds或者brace包装的 不如直接用下面的,不如直接使用下面的 <template><div ref"editor" class"json-editor"><…...
C++ 中的运算符重载
运算符重载是C中的一种特性,它允许开发者为自定义类型定义或改变标准运算符的行为。通过运算符重载,你可以使得用户定义的类像内置类型一样使用运算符,比如加法、减法、赋值等。 如何在C中进行运算符重载? 重载运算符的语法&#…...
渗透测试工具 -- SQLmap安装教程及使用
随着网络安全问题日益严峻,渗透测试成为了保护信息安全的重要手段。而在渗透测试的众多工具中,SQLmap凭借其强大的自动化SQL注入检测和利用能力,成为了网络安全专家必备的利器。那么,你知道如何高效地使用SQLmap进行漏洞扫描吗&am…...
使用 Database Tools 实现高效数据查询的十大 IntelliJ IDEA 快捷键
得益于 IntelliJ IDEA Ultimate 的 Database Tools(数据库工具)中的专用 SQL 查询控制台,您无需离开 IDE 即可轻松修改连接到您的 Java 应用程序的任何数据库中的数据,以及从这些数据库中提取数据。 查询控制台具有 SQL 语句特定的…...
SpringBoot 整合 RabbitMQ 实现流量消峰
RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用。 消息中间件在互联网公司的使用中越来越多,刚才还看到新闻阿里将 RocketMQ 捐献给了 Apache,当然了今天的主角还…...
大数据挖掘建模平台案例分享
大数据挖掘建模平台是由泰迪自主研发,面向企业级用户的大数据挖掘建模平台。平台采用可视化操作方式,通过丰富内置算法,帮助用户快速、一站式地进行数据分析及挖掘建模,可应用于处理海量数据、高复杂性的数据挖掘任务,…...
MySQL数据表的管理
1.创建表 语法: create table 表名( 字段名 字段里保存数据的类型【(数据的长度) 约束】, 字段名 字段里保存数据的类型【(数据的长度) 约束】, 字段名 字段里保存数据的类型【(数据的长度) 约束】 ...... ); 注意:数据类型和约束,接下来用…...
SpringBoot【十三(实战篇)】集成在线接口文档Swagger2
一、前言🔥 环境说明:Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 二、如何生成Swagger文档 上一期我们已经能正常访问swagger在线文档,但是文档空空如也,对不对,接下来我就教大家怎么把相关的接口都给…...
【C++初阶】第8课—标准模板库STL(string_2)
文章目录 1. string类对象遍历操作1.1 标准库中的成员函数begin( )和end( )1.2 标准库中的成员函数rbegin( )和rend( )1.3 C11引入的4个标准库中的成员函数 2. string类对象的访问2.1 operator[ ]运算符重载访问字符串字符2.2 公有成员函数at访问字符2.3 公有成员函数back()和f…...
【arm】程序跑飞,SWD端口不可用修复(N32G435CBL7)
项目场景: 国民N32G43X系列,烧录了一个测试程序,在DEBUG中不知什么原因挂掉,然后就无法连接SWD或JLINK。 问题描述 在SWD配置中不可见芯片型号,无法connect,无法烧录。但基本判断是芯片没有损坏。怀疑是程…...
https证书生成、linux 生成https证书、nginx 配置https证书
1. 检查 Certbot 是否已安装 which certbot 2. 安装 Certbot 2.1启用 EPEL 仓库(如果尚未启用): sudo yum install epel-release 2.2 安装 Certbot 和 Nginx 插件: sudo yum install certbot python3-certbot-nginx 2.3验证安…...
Halcon随机贴图生成缺陷图片脚本
halcon随机贴图生成缺陷图片,用于深度学习训练: read_image (Image, C:/Users/61082/Desktop/bentiiamge/omron/S06-1211/ok/ok_images/D246B_CPFNNUBA8LT0SX_AAA_S2412001793_C1216_1733895885320066.jpg) get_image_size (Image, Width, Height) gen_rectangle1 …...
[ZMQ] -- ZMQ通信Protobuf数据结构 1
1、前言背景 工作需要域间实现zmq通信,刚开始需要比较简单的数据结构,比如两个bool,后面可能就需要传输比较大的数据,所以记录下实现流程,至于为啥选择proto数据结构去做大数据传输,可能是地平线也用这个&…...
大数据平台
大数据行业应用持续升温,特别是企业级大数据市场正在进入快速发展时期。越来越多的企业期望实现数据孤岛的打通,整合海量的数据资源,挖掘并沉淀有价值的数据,进而驱动更智能的商业。随着公司数据爆发式增长,原有的数据…...
《C++解锁机器学习特征工程:构建智能数据基石》
在当今机器学习蓬勃发展的浪潮中,特征工程犹如一座坚实的基石,奠定了模型成功的基础。而 C以其卓越的性能和强大的底层控制能力,在实现机器学习特征工程方面发挥着独特且关键的作用。 特征工程的核心目标是从原始数据中提取和构建最具代表性…...
《机器学习》3.7-4.3end if 启发式 uci数据集klda方法——非线性可分的分类器
目录 uci数据集 klda方法——非线性可分的分类器 计算 步骤 1: 选择核函数 步骤 2: 计算核矩阵 步骤 4: 解广义特征值问题 と支持向量机(svm) 目标: 方法: 核技巧的应用: 区别: 使用 OvR MvM 将…...
【Linux】VMware 安装 Ubuntu18.04.2
ISO镜像安装步骤 选择语言 English 选择键盘布局 English 选择系统 Ubuntu 虚拟机网卡地址,默认即可 代理地址,默认空即可 镜像地址,修改成阿里云地址 选择第二项,LVM 磁盘扩容技术 第一块硬盘名sda,默认…...
人员离岗监测摄像机智能人员睡岗、逃岗监测 Python 语言结合 OpenCV
在安全生产领域,人员的在岗状态直接关系到生产流程的顺利进行和工作环境的安全稳定。人员离岗监测摄像机的出现,为智能人员睡岗、逃岗监测提供了高效精准的解决方案,而其中的核心技术如AI识别睡岗脱岗以及相关的算法盒子和常见的安全生产AI算…...
【Spark】Spark数据倾斜解决方案、大表join小表及大表join大表优化思路
如果觉得这篇文章对您有帮助,别忘了点赞、分享或关注哦!您的一点小小支持,不仅能帮助更多人找到有价值的内容,还能鼓励我持续分享更多精彩的技术文章。感谢您的支持,让我们一起在技术的世界中不断进步! Sp…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...
