Linux-自旋锁

概述

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

原理

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

  • 如果标志位为 false,表示锁可用,线程将设置标志位为 true,表示自己占用了 锁,并进入临界区。
  • 如果标志位为 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);

注意事项

  • 在使用自旋锁时,需要确保锁被释放的时间尽可能短,以避免 CPU 资源的浪费。
  • 在多 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);
}

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

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

相关文章

数据库中的JSON数据类型

数据库中的JSON&#xff08;JavaScript Object Notation&#xff09;数据类型是一种用于存储JSON格式数据的特殊数据类型。JSON是一种轻量级的数据交换格式&#xff0c;易于人们阅读和编写&#xff0c;同时也易于机器解析和生成。在数据库中引入JSON数据类型&#xff0c;可以使…

pikachu靶场SSRF-curl测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、实现ssrf攻击 四、源代码分析 五、结论 一、测试环境 1、系统环境 渗透机&#xff1a;本机(127.0.0.1) 靶 机&#xff1a;本机(127.0.0.1) 2、使用工具/软件 测试网址&#xff1a;…

DNS 与 ICMP

DNS(Domain Name System)快速了解 DNS 是一整套从域名映射到 IP 的系统 DNS 背景 TCP/IP 中使用 IP 地址和端口号来确定网络上的一台主机的一个程序. 但是 IP 地址不方便记忆 于是人们发明了一种叫主机名的东西, 是一个字符串, 并且使用 hosts 文件来描述主机 名和 IP 地…

微信开发者工具:音乐小程序报错

报错信息 GET http://localhost:3000/1.mp3 net::ERR CONNECTION REFUSED (env: Windows,mp,1.06.2303220;lib:3.6.0) 原因&#xff1a;小程序没有直接获取本地文件&#xff0c;为了提高访问速度&#xff0c;而采用放到网络服务器中网络访问的方式获取文件内容 解决办法&#…

测试主分支

测试主分支 输入汉字圆点.字母md有点别扭&#xff0c;以后锁定大小写&#xff0c;用.MD后缀 添加一行文字试试能不能自动从gitee同步到github 声明&#xff1a;本文使用八爪鱼rpa工具从gitee自动搬运本人原创&#xff08;或摘录&#xff0c;会备注出处&#xff09;博客&#…

JMeter如何设置HTTP代理服务器?

1、 2、添加线程组 3、设置HTTP代理服务器&#xff0c;目标控制器选择“测试计划>线程组” 过滤掉不需要的信息 4、设置电脑手动代理 5、点击启动&#xff0c;在浏览器操作就可以了

通过matlab建立excel,A1中输入F1,A2到A4为空。A5为F2,A6到A8为空。A9为F3依次类推。每个4个单元格增加1次F序号

% 初始化元胞数组 numElements 4 * 10; % 总共的元胞数量&#xff0c;按照每4个单元格一个F值来计算 str cell(numElements, 1); % 创建一个numElements x 1的元胞数组 % 填充元胞数组 for i 1:4:numElements str{i} [F, num2str(ceil(i/4))]; % 计算F后面的序号&a…

OpenCV-物体跟踪

文章目录 一、物体跟踪的定义二、OpenCV中的物体跟踪算法三、OpenCV物体跟踪的实现步骤四、代码实现五、注意事项 OpenCV是一个开源的计算机视觉和机器学习软件库&#xff0c;它提供了丰富的功能来实现物体跟踪。以下是对OpenCV中物体跟踪的详细解释&#xff1a; 一、物体跟踪的…

QT 如何置顶窗口并激活

基本上&#xff0c;客户端软件都会有置顶某个窗口的需求。置顶窗口激活窗口&#xff0c;两者不是同一个问题。有时候窗口置顶了&#xff0c;并不代表该窗口属于激活状态。本文将尝试把这两个问题一起解决了&#xff0c;请看下文&#xff1a; 一、置顶窗口 通过函数setWindowF…

Ubuntu16.04安装openssl库

Ubuntu16.04安装openssl库 Chapter1 Ubuntu16.04安装openssl库 Chapter1 Ubuntu16.04安装openssl库 原文链接&#xff1a;https://blog.csdn.net/weixin_36584476/article/details/107321893 记录一下省得忘了 1.首先去openssl官网下载源码www.openssl.org/source/&#xff0…

进程同步、互斥

进程同步、互斥的基本概念 系统中的某些资源&#xff0c;虽然可以提供给多个进程使用&#xff0c;但一个时间段内只允许一个进程访问该资源。 我们把一个时间段内只允许一个进程使用的资源称为临界资源。许多物理设备&#xff08;比如摄像头、打印机&#xff09;都属于临界资源…

python爬虫加解密分析及实现

第一种&#xff1a; 1、找到加密的接口地址&#xff0c;通过加密的接口地址全局搜索 2、通过打断点的方式&#xff0c;操作页面&#xff0c;跑到断点处时&#xff0c;即可找到加密串&#xff0c;如图二&#xff1b; 3、找到用的是哪种加密方式&#xff0c;如&#xff1a; cr…

Unity Apple Vision Pro 保姆级开发教程-准备阶段

视频教程&#xff1a; Unity PolySpatial 开发Apple Vision Pro教程, 三十分钟快速了解 Unity Vision Pro 中文课堂教程地址&#xff1a; Unity3D Vision Pro 开发教程【保姆级】 | Unity 中文课堂 开发Apple Vision Pro 使用原生开发和unity 开发有什么区别 如果你的项目需要…

python【装饰器】

装饰器&#xff08;decorators&#xff09;是 Python 中的一种高级功能&#xff0c;它允许动态地修改函数或类的行为。装饰器也称装饰函数&#xff0c;是一种闭包的应用&#xff1a;它接受一个函数作为参数&#xff0c;并返回一个新的函数或修改原来的函数。 基本语法 其主要是…

解决方案:总结描述下知识蒸馏、量化、剪枝的区别

文章目录 一、现象二、解决方案 一、现象 在算法中&#xff0c;时而会听到知识蒸馏、量化、剪枝这三个专业名词&#xff0c;进行记录 二、解决方案 知识蒸馏&#xff1a;一般将复杂、学习能力强的网络学到的特征表示“知识”蒸馏出来&#xff0c;传递给参数量小、学习能力弱…

LSTM反向传播及公式推导

先回顾一下正向传播的公式: 化简一下: 反向传播从下到上逐步求偏导: 对zt求偏导(预测值和标签值相减): zt对未知数wt,ht,bt分别求偏导: ht对ot,Ct求偏导: ot对Net0求偏导: Net0对w0,b0求偏导: .... 总体的思路就是那个公式从下到上逐步对未知数求偏导: 下面是总体的流程…

docker 资源限制+调优详解

容器资源限制介绍 下面我将详细讲解 Docker 的各种资源限制及其在生产环境中的实际应用案例。我们将逐一探讨 CPU、内存、磁盘 I/O 和网络带宽的限制&#xff0c;并提供具体的配置示例和解释。 1. CPU 限制 1.1 设置 CPU 份额 --cpu-shares&#xff1a;设置容器的 CPU 优先…

Nginx介绍+openresty配置

参考&#xff1a;资源下载 Nginx介绍openresty配置 nginx使用场景 1.什么是nginx性能高,官方测试5万并发连接;对cpu 内存资源消耗很低,而且运行非常稳定 免费 开源2.nginx应用场景1.http服务器静态资源 图片 js css 2.虚拟主机"虚拟"出多个主机, 域名80 www…

【AIGC】ChatGPT与人类理解力的共鸣:人机交互中的心智理论(ToM)探索

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;心智理论(Theory of Mind,ToM)心智理论在心理学与神经科学中的重要性心智理论对理解同理心、道德判断和社交技能的重要性结论 &#x1f4af;乌得勒支大学研究对ChatGPT-4…

设计一个多格式文件压缩与解压系统

设计一个多格式文件压缩与解压系统 在现代软件开发中,文件压缩和解压缩是一个常见且重要的需求。无论是为了节省存储空间,还是为了提高文件传输的效率,掌握文件压缩和解压缩的技术都是每个开发者必备的技能。本文将详细介绍如何设计一个支持多种压缩格式的文件压缩和解压系…