python与人工智能应用锁_linux应用锁的搜索结果-阿里云开发者社区

Linux中的spinlock和mutex

Linux中的spinlock和mutex

作者

digoal

日期

2016-11-09

标签

PostgreSQL , Linux , spin lock , mutex , 自旋锁 , 抢占锁

背景

最近在压测PostgreSQL同步流复制时,遇到一个mutex锁的瓶颈问题。

具体见 《PostgreSQL 同步流复制锁瓶颈分析》

PG是以backend process睡眠,然后通过sender唤醒的方式来处理同步等待的问题。

转一篇文章,了解一下spinlock, mutex。

http://www.aichengxu.com/view/2456962

spinlock (自旋锁)

自旋锁是专为防止多处理器并发而引入的一种锁,它在内核中大量应用于中断处理等部分(对于单处理器来说,防止中断处理中的并发可简单采用关闭中断的方式,不需要自旋锁)。

自旋锁最多只能被一个内核任务持有,如果一个内核任务试图请求一个已被争用(已经被持有)的自旋锁,那么这个任务就会一直进行忙循环——旋转——等待锁重新可用。

要是锁未被争用,请求它的内核任务便能立刻得到它并且继续进行。自旋锁可以在任何时刻防止多于一个的内核任务同时进入临界区,因此这种锁可有效地避免多处理器上并发运行的内核任务竞争共享资源。

事实上,自旋锁的初衷就是:

在短期间内进行轻量级的锁定。一个进程去获取被争用的自旋锁时,请求它的线程在等待锁重新可用的期间进行自旋(特别浪费处理器时间),所以自旋锁不应该被持有时间过长(等待时CPU被独占)。如果需要长时间锁定的话, 最好使用信号量(睡眠,CPU资源可出让)。

简单的说,自旋锁在内核中主要用来防止多处理器中并发访问临界区,防止内核抢占造成的竞争。另外自旋锁不允许任务睡眠(持有自旋锁的任务睡眠会造成自死锁——因为睡眠有可能造成持有锁的内核任务被重新调度,而再次申请自己已持有的锁),它能够在中断上下文中使用。

死锁:假设有一个或多个内核任务和一个或多个资源,每个内核都在等待其中的一个资源,但所有的资源都已经被占用了。这便会发生所有内核任务都在相互等待,但它们永远不会释放已经占有的资源,于是任何内核任务都无法获得所需要的资源,无法继续运行,这便意味着死锁发生了。自死琐是说自己占有了某个资源,然后自己又申请自己已占有的资源,显然不可能再获得该资源,因此就自缚手脚了。

spinlock特性:

防止多处理器并发访问临界区,

1、非睡眠(该进程/LWP(Light Weight Process)始终处于Running的状态)

2、忙等 (cpu一直检测锁是否已经被其他cpu释放)

3、短期(低开销)加锁

4、适合中断上下文锁定

5、多cpu的机器才有意义(需要等待其他cpu释放锁)

信号量与互斥量

Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。

信号量的睡眠特性,使得信号量适用于锁会被长时间持有的情况;只能在进程上下文中使用,因为中断上下文中是不能被调度的;另外当代码持有信号量时,不可以再持有自旋锁。

信号量基本使用形式为:

static DECLARE_MUTEX(mr_sem); //声明互斥信号量

if(down_interruptible(&mr_sem))

//可被中断的睡眠,当信号来到,睡眠的任务被唤醒

//临界区

up(&mr_sem);

struct semaphore数据类型,down(struct semaphore * sem)和up(struct semaphore * sem)是占用和释放

struct mutex数据类型,mutex_lock(struct mutex *lock)和mutex_unlock(struct mutex *lock)是加锁和解锁

竞争信号量与互斥量时需要进行进程睡眠和唤醒,代价较高,所以不适于短期代码保护,适用于保护较长的临界区

互斥量与信号量的区别

1. 互斥量用于线程的互斥,信号量用于线程的同步

这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别

互斥:

是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的

同步:

是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源

2. 互斥量值只能为0/1,信号量值可以为非负整数

也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问

3. 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到

特性:

1、睡眠 (系统会将CPU切换给其他的进程/LWP运行。)

2、必须进程上下文(可调度)

3、长期加锁

信号量和自旋锁区别

虽然听起来两者之间的使用条件复杂,其实在实际使用中信号量和自旋锁并不易混淆。注意以下原则:

如果代码需要睡眠——这往往是发生在和用户空间同步时——使用信号量是唯一的选择。由于不受睡眠的限制,使用信号量通常来说更加简单一些。

如果需要在自旋锁和信号量中作选择,应该取决于锁被持有的时间长短。理想情况是所有的锁都应该尽可能短的被持有,但是如果锁的持有时间较长的话,使用信号量是更好的选择。

另外,信号量不同于自旋锁,它不会关闭内核抢占,所以持有信号量的代码可以被抢占。这意味者信号量不会对影响调度反应时间带来负面影响。

自旋锁和信号量的选择

需求

建议的加锁方法

低开销加锁

优先使用自旋锁

短期锁定

优先使用自旋锁

长期加锁

优先使用信号量

中断上下文中加锁

使用自旋锁

持有锁是需要睡眠、调度

使用信号量

以上有部分内容转自 http://www.linuxidc.com/Linux/2011-03/33741.htm

以下内容转自 http://blog.sina.com.cn/s/blog_0001988f0101f42l.html

spinlock mutex语义上是一样的,都是对一临界区加锁保护,

区别是mutex得不到锁会睡眠,因此不能在中断上下文中使用。

另外,解锁的一定是上锁的那个 semaphore 得不到锁会睡眠,也不能用在中断中, 上锁的不一定负责解锁 。

rwlock 很好理解了,可多个读,只有一个写者,同样会引起睡眠

最重要的就是只有spinlock 可以用在中断上下文中.

至于wait_queue,不是同步手段,是内核管理sleeping进程的一种手段

什么是等待队列?

在软件开发中任务经常由于某种条件没有得到满足而不得不进入睡眠状态,然后等待条件得到满足的时候再继续运行,进入运行状态。这种需求需要等待队列机制的支持。

而且semaphore(我不知道所有的实现是不是这样)中也用到了wait_queue_head

spinlock和信号量sem的区别

重点:死循环/睡眠

spinlock只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁。sem则会导致调用睡眠。然后应用上就是前者可以在中断处理中使用,后者不行。

信号量是针对使用时间比较长的共享资源,而自旋锁的则一般时间较短.一般的申请锁被其它保存则循环不止的等待.

Spinlock不断的检查等待的对象是否就绪,该进程/LWP始终处于Running的状态

Sem使该进程/LWP进入Wait转台,系统会将CPU切换给其他的进程/LWP运行。

由于这个根本特性的不同,导致了以下用法上的不同:

1. Spinlock 只适用于短暂的等待,因为没有进程切换所以对于短暂等待他的效率会比较高。但是对于长时间等待,由于它的CPU占用是100% 等的越长越不合算。

2. Spinlock只能在多个CPU的系统上用,因为等待者占据了100%的CPU,只由另外一个CPU上的进程才能解锁。

两者都是用于Linux内核互斥。避免并发,防止竞争,对系统公共资源或者共有数据进行合理保护的。SpinLock的出现是因为Symmetric Multi-Processor的出现,如果是UniProcessor,用简单的DisableIRQ就可以满足其要求。Spin Lock是通过Poll方式的,其可以说是一个Test and Set or Test andClear的模型的延伸。而Semaphore则是传统的IPC,是通过Sleep and Wake up方式实现的。通过SpinLock and Semaphore两者的实现机制则,我们可以很明晰的看出两者的应用场合。

(在高并发的地方,轮询比睡眠更高效)

Semaphore是一件可以容纳N人的房间,如果人不满就可以进去,如果人满了,就要等待有人出来。对于N=1的情况,称为binarysemaphore。一般的用法是,用于限制对于某一资源的同时访问。

Binarysemaphore与Mutex的差异:

在有的系统中Binarysemaphore与Mutex是没有差异的。在有的系统上,主要的差异是mutex一定要由获得锁的进程来释放。而semaphore可以由其它进程释放(这时的semaphore实际就是个原子的变量,大家可以加或减),因此semaphore可以用于进程间同步。Semaphore的同步功能是所有系统都支持的,而Mutex能否由其他进程释放则未定,因此建议mutex只用于保护criticalsection。而semaphore则用于保护某变量,或者同步。

另一个概念是spin lock,这是一个内核态概念。spinlock与semaphore的主要区别是spin lock是busywaiting,而semaphore是sleep。对于可以sleep的进程来说,busywaiting当然没有意义。对于单CPU的系统,busywaiting当然更没意义(没有CPU可以释放锁)。因此,只有多CPU的内核态非进程空间,才会用到spin lock。Linuxkernel的spinlock在非SMP的情况下,只是关irq,没有别的操作,用于确保该段程序的运行不会被打断。其实也就是类似mutex的作用,串行化对critical

section的访问。但是mutex不能保护中断的打断,也不能在中断处理程序中被调用。而spinlock也一般没有必要用于可以sleep的进程空间。

spinlock是多CPU下的同步机制,在获取锁时,如果失败,它不会挂起当前的执行过程。与之相对的,mutex和semaphore等同步机制,如果获取mutex或semaphore失败,它会挂起当前的执行过程,而在mutex或semaphore退出是,唤醒相应的过程。

不同的同步机制,是为了解决不同的问题。在单cpu上,不可能有spinlock,因为当前只能有一个活动的执行路径。而mutex或者semaphore则可以挂起当前的线程或者进程,CPU这时可以做其他的事情,等到挂在mutex或者semaphore上的进程被唤醒时,再继续执行被挂起的路径。

可以想象,spinlock的设计并不是不能支持挂起当前执行过程的操作。只是,在内核中,挂起当前的执行过程,就必须先能够标识这个过程。内核线程,或者进程,都有相应的结构;但是,哪些不属于这两种的执行过程,就必须使用spinlock。还有,如果一组进程在执行过程中,要求必须是同步执行,不能被打断,这种情况下spinlock也是必须的。

说了这么多,主要的意思就是说,不能的同步机制适用于不同的场景,解决不同的问题。没有一种同步机制可以解决所有的问题,这也是为什么linux里面不断有新的同步机制被引入内核。当新的问题出现时,现有的机制不能解决,或者不能很好解决这个问题时,就有必要引入新的机制来解决这个问题。

锁是一种协议,是有共享临界区的执行过程之间达成的协议。有了api,并不能保证程序的正确,还需要正确的,合理的使用api。尤其是在多cpu情况下,锁的使用,对性能有很大的影响。最好的办法就是不使用锁,每个CPU都是完全独立的运行。这也要看具体的应用,如果数据之间没有关联,当然可以独立地去处理;反之,则必须要锁来保护。

比如用multicore实现网络包的转发时,当然可以把某个流绑定到某个CPU上,假设流与流直接是完全独立的,这种情况下,每个CPU都可以独立的处理属于自己的流,不需要和其他CPU共享数据。但是,由于不同的流,流量是不同的,这样,CPU的能力没有被充分的利用,资源的使用也不平衡。这样的设计并不能很好的解决问题。

选择哪种设计方案,要综合的去考虑,没有最完美的解决方案,因为很多需求是相互冲突的,一个折衷的方案就是最后的选择。

文章

关系型数据库 · Linux · 调度 · PostgreSQL

2016-11-24

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

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

相关文章

hfss和matlab,hfss和MATLAB联合仿真

hfss中仿真太费时间,而且是在做优化,能否进行hfss和matlab联合仿真,利用模拟退火算法缩短仿真时间?可能我的问题描述的不是特别清楚,我不是想要具体的解决方案,只希望有相关资料的人能提供给小弟一点资料,…

c++代码健壮性_复活Navex-使用图查询进行代码分析(上)

从了解到修复 Navex, 其中花了一年多, 从对自动化代码审计一无所知到学习PL/Static Analysis, 翻阅十几年前的文档, 补全Gremlin Step, 理解AST, CFG, DDG, PDG, CPG, 也感谢z3r0yu师傅和Gaba哥的的交流指导.本文重点在于静态分析 Joern-图查询部分, 后面的动态分析自动生成EXP…

公文字体字号标准2020_一文了解公文格式规范,图文并茂(建议收藏备用)

本方法根据《党政机关公文格式国家标准》(GB/T9704-2012)制定。具体内容如下:一、办公软件要求适用于微软OFFICE—WORD文字处理软件。二、页面设置1.选择“文件”——“页面设置”选择“页边距”附签,上:3.7厘米,下:3.…

360浏览器卸载_无法卸载?Win10 强推新 Edge 浏览器,来教你如何干掉它

8月17日消息,相信不少更新了 Windows 10 v2004 版本的用户都已经发现,系统默认浏览器已经自动更新为基于 Chromium 打造的全新 Edge 浏览器,虽然该浏览器已经一跃成为全球第二大桌面浏览器,但却仍然有不少用户反馈不好用。撰文 | …

python gridsearch_python gridsearch中的内存错误

我需要应用网格搜索我有20000列和110000行的数据帧,我需要使用python的网格搜索模块调整我的参数#validation for svm#there are an error to check it ( grid search ne marche pas i will check why after)label df.Sentimenttrain df.drop(Sentiment, axis1)fro…

磁卡门锁怎么配卡_样式多的铜工艺品怎么设计请查看_江西南昌皇巢|铜门||别墅铜门|...

江西南昌皇巢|铜门||别墅铜门|专注FNbnWz样式多的铜工艺品怎么设计请查看,咨询更多详情!KLC欧式门锁室内门锁卧室房门锁黄古铜门锁实木门锁具执手锁¥,月销笔进店相关推荐词军升欧式门锁黄古铜田园室内门锁执手机械门锁卧室锁具防盗…

php怎么分割页面,用html如何把页面分割成多个文件,由多个文件拼接而成?

用html如何把页面分割成多个文件,由多个文件拼接而成?更新时间:2014-11-10 作者:久久经验网 来源:久久经验网 所属分类:Web前端摘要:静态html分割页面,达到类似php等动态页面的in…

python xml字符串_python -解析字符串,并返回xml格式字符串 急该如何解决

python --解析字符串&#xff0c;并返回xml格式字符串 急急急。str """Registrations:Call-ID: 8945da7a7f550c16NWRjZjdmMjhmNWQxYTZlOTJjMDY5YjhiN2RjMDViMWE.User: 1000192.168.1.111Contact: "1000" <1000>1000&g…

13寸笔记本电脑尺寸_如何判断行李箱的尺寸?标准行李箱尺寸对照表(13~32寸)

行李箱已经成为家庭必备的一件物品&#xff0c;很多时候都会用到行李箱&#xff0c;最晚就是大学时期&#xff0c;肯定会准备一个行李箱&#xff0c;有些人第一次买不知道如何判断行李箱的尺寸&#xff0c;今天小编就教大家怎么自己确定行李箱的尺寸。如何判断行李箱的尺寸?行…

python列表转字节_如何在Python中将十进制数转换为字节列表

How do you turn a long unsigned int into a list of four bytes in hexidecimal?Example...777007543 0x2E 0x50 0x31 0xB7解决方案The simplest way I can think of is to use the struct module from within a list comprehension:import structprint [hex(ord(b)) for b…

php里忽略输入数值里的空格,input在标签内设置禁止输入空格

video&period;js1.github地址 2.常用API: class : video-js: video-js应用视频所需的风格.js功能,比如全屏和字幕. vjs-default-skin: vjs-default- ...NSMutableAttributedString 富文本删除线的用法#import //价格 NSString *priceStr "99元 剁手价66元"; NSM…

华为手机怎么隐藏按键图标_mac桌面图标怎么快速隐藏?

我们会应为方便而在电脑桌面直接放一些文件&#xff0c;对于处女座而言无论是桌面还是电脑桌面都不希望非常凌乱&#xff0c;那么我们如何隐藏我们的mac电脑桌面图标文件呢&#xff1f;如何才能使电脑看起来干净整洁呢&#xff1f;一、如何在 Finder 中隐藏桌面图标&#xff1f…

bat脚本中如何多次键盘输入并判断_电脑上如何多开微信?PC端多开微信的方法

相信很多人都有多个微信&#xff0c;尤其是那些工作和生活分的比较开的人士&#xff0c;大家都知道一个电脑和可以登录多个QQ的&#xff0c;但是对于微信却不是这样。当你已经登录一个微信时&#xff0c;再打开微信时会自动弹出当前已经登录的微信窗口。本文将教你如何在PC电脑…

php配置实例,php mailto配置实例

本节内容&#xff1a;php mail to的配置方法。1&#xff0c;配置文件[mail function]; For Win32 only.SMTP mail3.jbxue.comsmtp_port 25; For Win32 only.;sendmail_from meexample.com说明&#xff0c;仅用于测试&#xff0c;所以没有用到用户名和密码&#xff0c;测试代…

python创建dataframe表格不显示_创建列pandas DataFrame数据的表绘图时出现问题?

我有下面的代码&#xff0c;它创建一个带有标签的列名的表映像。我遇到的问题是让列(dc[x])能够垂直填充表&#xff0c;而不是水平填充。在def drilltable():c readcsv3()dc DataFrame(c)topA,ARA,PWA, dc[0],dc[1],dc[2],data[topA,ARA,PWA]fig plt.figure()ax fig.add_s…

win7蓝牙怎么连接_win7添加打印机提示windows无法连接怎么办?正确解决方法分享...

如果有多台电脑&#xff0c;那么一般会把打印机设置成共享&#xff0c;然后其他电脑通过添加网络打印机的方式来使用。有win7纯净版系统用户遇到一个问题&#xff0c;在自己电脑上要添加另一台电脑共享的打印机时&#xff0c;出现“Windows无法连接到打印机。键入的打印机名不正…

python随机产生100个整数二进制_PYTHON练习题 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数。...

Python 练习标签&#xff1a; Python Python练习题 Python知识点二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数&#xff0c;如果大于预设的数&#xff0c;屏幕显示“太大了&#xff0c;请重新输入”如果小于预设的数&#xff0c;屏幕显…

一般项目中哪里体现了数据结构_优秀程序员都应该学习的数据结构与算法项目(GitHub 开源清单)...

前言算法为王。想学好前端&#xff0c;先练好内功&#xff0c;内功不行&#xff0c;就算招式练的再花哨&#xff0c;终究成不了高手&#xff1b;只有内功深厚者&#xff0c;前端之路才会走得更远。强烈推荐 GitHub 上值得前端学习的数据结构与算法项目&#xff0c;包含 gif 图的…

matlab多元约束最小值,无约束多变量最小值求解问题

%%%建立函数f&#xff0c;包含u0、v0、k1、k2四个未知参数&#xff1b;function fmyfun(x);u0x(1);v0x(2);k1x(3);k2x(4);%x、y为两个4*4矩阵&#xff0c;存储16个坐标值&#xff1b;x[840.224650000000,941.255360000000,1041.80517000000,1141.57622000000;839.663680000000,…

python open ascii codec cant_Python3.6 报错问题:'ascii' codec can't encode character

当我使用 urllib.request.urlopen 访问 http://api.map.baidu.com/telematics/v3/weather?outputjson&location北京&ak**** 的时候&#xff0c;程序报错了&#xff1a;1 #!D:/Program Files/Python3623 importurllib.request45 classWeatherHandle:67 #初始化字符串8 …