首页 > 系统相关 >linux之自旋锁(二千字长文)

linux之自旋锁(二千字长文)

时间:2024-01-28 11:01:04浏览次数:27  
标签:小明 小王 二千 linux 临界 线程 自旋 字长 等待

linux之自旋锁

常见的各种锁

悲观锁:在每次取数据时,总是担心数据会被其他线程修改,所以会在取数据前先加锁(读锁,写锁,行锁等),当其他线程想要访问数据时,被阻塞挂起。

总是先行认为数据一定会被修改!所以要先加锁!保证没有人能够访问它!

==我们学的同步互斥机制!其实都是属于悲观锁的范畴!==

乐观锁:每次取数据时候,总是乐观的认为数据不会被其他线程修改,因此不上锁。但是在更新数据前,会判断其他数据在更新前有没有对数据进行修改。主要采用两种方式:版本号机制和CAS操作。

CAS操作:当需要更新数据时,判断当前内存值和之前取得的值是否相等。如果相等则用新值更新。若不等则失败,失败则重试,一般是一个自旋的过程,即不断重试。

这个在java更加的常见!

自旋锁,公平锁,非公平锁?

自旋锁(修改)

像是互斥锁,信号量,当我们申请失败了!那么进程在系统级别上就会被挂起——这种我们一般都称之为挂起等待锁

对于临界资源,我们可以加锁保护!然后对临界资源进行区域性的使用!——例如:环形队列!

为了能够理解自旋锁我们先举个例子

有一天小明去找小王玩,到小王家楼下,小明就给小王打电话,叫小王出去一起玩!

但是小王说他要做作业,要等等!小明说那可以!小明于是就在楼下等起来了!小明等了好一会,但是小王还没有下了,于是小明又打电话,小王说还要等等,小明是一个急性子,于是每等一会就要给小王打电话!最后小王终于好了!然后一起去玩了

小明和小王玩的很开心,于是小明隔天又来找小王玩!小明到了之后给小王打电话!但是小王说他又在写作业!小明他想到昨天等了那么久!所以今天不想等了!于是小明说,他先去隔壁的网吧玩!你写作业快好了就给他提前打个电话!他就再去楼下等他!

小王觉得也挺好的!省的小明一直给他打电话!小明玩着玩着,小王给他打电话!这时候,小明就回去了去楼下等,此时小王很快就下来了!

在故事当中,第二天,小明给小王打电话!小明觉得等着很久,于是不等了,打算去网吧做自己的事情!——==翻译过来就是当前的线程,去尝试的申请锁!发现上一个线程要在临界资源里待了很久,所以不打算等!所以将自己挂起!(从楼下到网吧这就是挂起的过程,葱网吧到楼下就是唤醒的过程!)==——这就是一种挂起等待的过程!

在故事中!第一题小明去找小王!小明向小王打电话!好了没?没有就挂电话!直到好之前,一直循环这个过程!——==即一个线程,不断的向另一个线程询问是否就绪!这种状态就是自旋!(自旋的过程就是轮询的过程!)==

==那么是什么决定了最终的等待方式?==

假如小王说,我1分钟后就下来,小明打电话说,我先去网吧,要下来了再打我电话合适吗?!——不合适!保不定还没有到小王就到楼下了!

那么小王说,1小时后再下来!那么此时去网吧等待就合适了!小明一直给小王打电话!反倒会影响的效率!

==所以决定了最终的等待方式的问题其实是——我们要等待的时长的问题!==

们以前研究过,如何整体访问临界资源!如何部分访问临界资源!如何加锁!——但是我们从来没有研究已经申请过锁的线程去访问这个共享资源需要多长时间!——即已经被申请的临界资源,决定了其他线程就要等待!

==一个成功申请临界资源的线程,在临界区内要待多长时间!就直接决定了我们使用的的是挂起等待锁,还是自旋!==

如果时间长——那么就挂起等待!如果时间短那么就——自选(轮询)

修改

如何评估线程待在临界区时间长短!

在代码层面我们去理解是很难有一个结论的!——重点是要结合场景!

==但是一般来说——当临界区里面有高复杂度的计算!IO操作,等待某转软件条件!大概率是要挂起等待的!==

==如果临界区里面!仅仅是一个简单的内存操作!一些代码很短,执行速度很快的代码我们就可以采用自旋锁!==

**不过自旋我们一般很少会去使用!因为虽然自选在==正确的评估时间长短的情况下==确实是比挂起等待更快!——==但是一旦评估出错!就会大量的消耗CPU资源!==**而且如果是在挂起等待的时候出现死锁!那么无非就是两个线程互相阻塞!但是一般自旋锁里面出现了类似死锁的情况!所有的执行流都会疯狂的自旋检测锁的状态!没有人去释放锁!那么就有可能会让我们的CPU瞬间就被打满!==所以自旋锁是有危险的!大部分没有特殊要求的情况下,或者及其确定使用自旋锁不会出问题且场合十分适合自旋!都是推荐使用挂起等待!==

因为评估在临界资源的长短是由程序员来决定的!使用那个方案也是由程序员来决定的!所以当如果我们真的不确定!我们可以选择都用一次!分别测试一下!那个效率高用那个!

一般系统层面代码使用的自旋锁更多!用户层面使用的会少一些

自旋锁的接口

初始化接口

image-20230828111422471

pthread_spinlock_t,这个就是自旋锁的类型!

pshared参数是表示共享级别!0表示线程间不共享!非0就是表示与其他线程共享!

加锁接口

image-20230828111224662

自旋的过程是不用我们自己做的!

想要自己做也是可以的!——使用try_lock如果申请失败就可以自己去实现

解锁接口

image-20230828112336594

无论是挂起等待还是自旋!——正在别的线程看来其实都是在等待!

==用法其实和互斥锁是一样的!==

标签:小明,小王,二千,linux,临界,线程,自旋,字长,等待
From: https://blog.51cto.com/u_15835985/9452263

相关文章

  • 《PalWorld/幻兽帕鲁》旧电脑linux搭建服务器
    关键词:PalWorld,Linux,Natapp,内网穿透,幻兽帕鲁 注意文章时效性 最近幻兽帕鲁爆火,steam一上线好友列表一串正在游玩哈哈哈,自己也是蹭一波热度,顺便试用一下natapp以及联系一下写文章的能力,嘿嘿 首先说明下环境Linux:ubuntu22.04.1Natapp:2.4.0#我用......
  • 查看、清空Linux日志【系统日志、软件运行日志】
    一、各种系统日志文件位置123456789101112131415/var/log/messages:记录Linux内核消息及各种应用程序的公共日志信息 /var/log/cron:      记录crond计划任务产生的事件信息 /var/log/dmesg:     记录Linux操作系统在引导过程......
  • 第十四天:Linux启动流程
    一、CentOS6之前版本的启动流程1.1硬件启动POSTPOST:Power-On-Self-Test,加电自检,是BIOS功能的一个主要部分。负责完成对CPU、主板、内存、硬盘子系统、显示子系统、串并行接口、键盘等硬件情况的检测主板的ROM:BIOS,BasicInputandOutputSystem,保存着有关计算机系统最重要......
  • 最近在学Linux系统记录一下
    Linux系统维基百科介绍CentOS(CommunityEnterpriseOperatingSystem)是Linux发行版之一,它是来自于RedHatEnterpriseLinux(RHEL)依照开放源代码规定发布的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定性的服务器以CentOS替代商业版的RedHatEnterpriseLinux使......
  • Burp Suite Professional 2024.1.1 (macOS, Linux, Windows) - Web 应用安全、测试和
    BurpSuiteProfessional2024.1.1(macOS,Linux,Windows)-Web应用安全、测试和扫描BurpSuiteProfessional,Test,find,andexploitvulnerabilities.请访问原文链接:https://sysin.org/blog/burp-suite-pro/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgB......
  • Linux之openssl实现私有CA
    一、简介Centos7.9通过openssl工具构建一个私有的CA,用于颁发证书。验证私有CA为httpd应用签署证书二、构建私有CA1、编辑CA的配置文件[root@HLWHOSTtls]#pwd/etc/pki/tls[root@HLWHOSTtls]#cat/etc/pki/tls/openssl.cnf...########################################......
  • 在 Python 的 `glob` 模块中,文件名的大小写敏感性取决于你的操作系统。在 Unix 和 Lin
    在Python的`glob`模块中,文件名的大小写敏感性取决于你的操作系统。在Unix和Linux系统中,`glob`是区分大小写的。然而,在Windows和MacOS中,`glob`是不区分大小写的。例如,如果你在Unix或Linux系统中运行以下代码:```pythonimportglobfiles=glob.glob('*.xlsx')......
  • Linux基础命令笔记(黑马)
    Linux基础命令Linux常用快捷键ctrl+c:强制停止程序运行ctrl+d:退出用户登录或某些特定程序的专属页面(不能用于vim)!历史命令前缀:执行历史中最后使用带有该命令前缀的命令例:!p相当于python、!t相当于tailctrl+r:可输入历史命令关键字搜索到想要到命令,按回车直接执行,按左......
  • Linux命令:userdel 删除用户账户
    userdel命令使用1.删除用户账户$sudouserdeluser12.删除用户账户,并删除用户『主目录』和『邮件』【-r/--remove】$sudouserdel-ruser19$sudouserdel--removeuser203.强制删除用户账户【-f/--force】$sudouserdel-fuser1$sudouserdel--force......
  • linux创建新用户
    1、创建用户名和密码sudoadduser2、授予sudo权限回到root账户,输入chmodu+w/etc/sudoers授予读写权限输入vim/etc/sudoers找到这行rootALL=(ALL)ALL,在他下面添加xxxALL=(ALL)ALL(这里的xxx是你的用户名)(注意ALL三个字母全是大写的!!!)3、给docker命令sudo权限为了......