Linux -- 管理锁争用(翻译)
在多线程应用中,程序员会使用互斥锁(mutex)来同步线程进入可访问共享资源的代码区域的行为。受这些锁保护的代码区域被称为关键代码段(Critical Section)。如果关键代码段中已存在一个线程,那么其他任何线程都不可进入该代码段。
线程应该尽量缩短在关键代码段花费的时间,进而减少其他线程在代码段外闲置等待获得锁的时间。但是又不能盲目地划分出很多的小代码段。
例1
Begin Thread Function ()
Initialize ()
BEGIN CRITICAL SECTION 1
UpdateSharedData1 ()
END CRITICAL SECTION 1
DoFunc1 ()
BEGIN CRITICAL SECTION 2
UpdateSharedData2 ()
END CRITICAL SECTION 2
DoFunc2 ()
End Thread Function ()
上例中,关键代码段被DoFunc1 ()函数分离开来。
如果线程在DoFunc1 ()中花费的时间很长,这样做是值得的。
但是如果线程在DoFunc1 ()中花费的时间很短,那更好的方案是将两个小关键代码段合并为一个关键代码段
例2
Begin Thread Function ()
Initialize ()
BEGIN CRITICAL SECTION 1
UpdateSharedData1 ()
DoFunc1 ()
UpdateSharedData2 ()
END CRITICAL SECTION 1
DoFunc2 ()
End Thread Function ()
例1中,关键代码段被DoFunc1 ()函数分离开来。UpdateSharedData1 ()和UpdateSharedData2 ()分别由两个锁来同步。例2中,将两个小关键代码段合并为一个大的关键代码段,其中包含了与同步无关的函数DoFunc1 ()。
那么哪种选择更好呢?
这要看情况决定。
如果线程在DoFunc1 ()中花费的时间很长,例1的性能更好。因为例2里,线程获得了锁,却在关键代码中浪费了大量的时间到与同步无关的函数上。
如果线程在DoFunc1 ()中花费的时间很短,例2的性能更好。例1为了在关键代码段中减少DoFunc1 ()的时间,承受了同步两个关键代码段的锁争用开销。如果DoFunc1 ()的时间少于1个锁争用开销,那么例1反而损失了性能。
如果线程在UpdateSharedData2 函数上会花费较长时间,例1的性能更好。因为这种情况下,线程无可避免地将在关键代码段中花费很长的时间。例2中,当线程进入UpdateSharedData2函数时,所有其他线程都堵塞着等待进入UpdateSharedData1函数。因此,我们可以采用例1 ,让其他线程先处理完UpdateSharedData1函数。
尽量把锁关联到特定共享数据。你不应该为共享数据的结构中的每个元素创建一个独立的锁,也不应该创建单个锁来保护到整个结构的访问。最佳的锁粒度应该在这两者之间,需要你把握。
针对上面的最后一个情况(如果线程在UpdateSharedData2 函数上会花费较长时间)
- 把UpdateSharedData2 函数访问的数据结构分为两部分,各使用一把互斥锁。然后把UpdateSharedData2 函数分解为两个函数。通过分离关键代码的方式来减少锁争用。
- 分析UpdateSharedData2 函数,如果UpdateSharedData2 函数并不需要对整个执行过程进行保护,那你可以考虑在函数中需要访问共享数据的点插入关键代码段,而不是封闭整个函数调用。
根据获取和释放锁的开销来调整关键代码段的大小。我们可做的事有:
- 整合小关键代码段,以分担锁定开销。
- 将锁争用现象严重的大型关键代码段划分为较小的关键代码段。
- 将锁关联至特定的共享数据,借以最大限度减少锁争用问题。 最佳解决方案可能处于为每个共享数据元素创建一个锁和为所有共享数据创建一个锁两种极端之间。
采用大关键代码段意味着算法本身的并发性非常低,或者线程间的数据划分并不理想。 对于前者,只能更改算法。 对于后者,可尝试为共享数据创建本地拷贝,支持线程异步访问。
如果我们考虑上下文切换的开销,那么我们应该决定使用互斥锁还是自旋锁。自旋锁是一个等待循环,会一直占用CPU,因此没有上下文切换。对于正等待进入小关键代码段的线程来说,使用自旋锁可能比互斥锁有更高的性能。但是,鉴于处于等待状态的线程在旋转等待循环中仍将占用 CPU 资源, 只有当线程在关键代码段中所花费的时间极短,不良影响低于环境切换时,才推荐使用旋转等待循环。
在支持英特尔® 超线程技术(英特尔® HT 技术)的处理器中,会在同一 CPU 核心上创建两路逻辑处理器。 旋转线程和正执行有用任务的线程务必会争夺逻辑处理器资源。与对称多处理器系统相比,旋转线程对采用英特尔超线程技术的系统中多线程应用性能的影响更大。 在这种情况下,应将自旋锁的自旋计数调低,或者不采用自旋锁。
Linux -- 管理锁争用(翻译)的更多相关文章
- [转]了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密_Mr_Indigo的空间
了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密 关系型数据库,如SQL Server,使用锁来避免多用户修改数据时的并发冲突.当一组数据被某个用户锁定时,除非第一个用户结束修 ...
- 了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密
关系型数据库,如SQL Server,使用锁来避免多用户修改数据时的并发冲突.当一组数据被某个用户锁定时,除非第一个用户结束修改并释放锁,否则其他用户就无法修改该组数据. 有些数据库,包括SQL Se ...
- 在Linux下锁住键盘和鼠标而不锁屏
假如在你正看着屏幕上的某些重要的事情时,你不想让你的小猫或者小狗在你的键盘上行走,或者让你的孩子在键盘上瞎搞一气,那我建议你试试 xtrlock 这个工具. 假如在你正看着屏幕上的某些重要的事情时,你 ...
- 调整Kali Linux的锁屏时间
调整Kali Linux的锁屏时间 锁屏是保护隐私的一种重要机制.当用户不操作电脑一段时间后,系统会进入锁屏状态.用户需要输入口令,才能重新进入系统.避免因为操作人员离开电脑后,被其他人员利用现有 ...
- Kali Linux 网络扫描秘籍 翻译完成!
Kali Linux 网络扫描秘籍 翻译完成! 原书:Kali Linux Network Scanning Cookbook 译者:飞龙 在线阅读 PDF格式 EPUB格式 MOBI格式 代码仓库 ...
- linux管理面板
小编在这儿给大家介绍几款linux管理面板,希望感兴趣的童鞋可以去尝试下.个人觉得宝塔和appnode这两个面板不仅从功能和样式都还是做的比较好的,但是部分功能是收费的,但是webmin绝对是一款免费 ...
- linux 管理权限
linux 管理权限 linux 文件 权限 1.使用 ls -l 命令 执行结果如下(/var/log) : drwxr-x--- 2 root adm 4096 2013-08-07 11:03 ...
- Linux 管理环境变量的文件分为系统级和用户级别
Linux 管理环境变量的文件分为系统级和用户级别 管理环境变量的文件也分为系统级和用户级别: 1.系统级:/etc/profile:该文件是用户登录时,操作系统定制用户环境时使用的第一个文件,应用于 ...
- mysql 开发进阶篇系列 7 锁问题(innodb锁争用情况及锁模式)
1 .获取innodb行锁争用情况 1.1 通过检查innodb_row_lock状态变量来分析系统上的行锁的争夺情况 SHOW STATUS LIKE 'innodb_row_lock%' 通过in ...
随机推荐
- jmeter接口测试json详解
本篇围绕jmeter(压力测试工具),请求json与返回json串处理进行解析,初入测试,理解如有不对的地方请大家及时提点~~ 在这里jmeter工具的使用不在做解释 首先说下乱码问题,在这里无脑5步 ...
- RMQ问题【模板】
概念 RMQ 是英文 Range Maximum/Minimum Query 的缩写,表示区间最大(最小)值. 解决 RMQ 问题的主要方法有两种,分别是 ST 表和线段树.本文主要讲 ST 表. S ...
- Vue IE11 报错 Failed to generate render function:SyntaxError: 缺少标识符 in
报错截图: 查了篇文章(https://blog.csdn.net/weixin_42018057/article/details/81385121),遇到的情况跟文章里描述的类似,他提供的方法是:需 ...
- 洛谷 P1309 瑞士轮 题解
每日一题 day4 打卡 Analysis 暴力+快排(其实是归并排序) 一开始天真的以为sort能过,结果光荣TLE,由于每次只更改相邻的元素,于是善于处理随机数的快排就会浪费很多时间.于是就想到归 ...
- 006_Python3 数字(Number)
1. Python 数字数据类型用于存储数值. 数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间. 以下实例在变量赋值时 Number 对象将被创建: var1 = ...
- jQuery相关方法5----表单相关
一.value属性在表单的相关操作-----val()方法 <script src="http://libs.baidu.com/jquery/1.10.2/jquery.min.js ...
- Python3 内置http.client,urllib.request及三方库requests发送请求对比
如有任何学习问题,可以添加作者微信:lockingfree 更多学习资料请加QQ群: 822601020获取 HTTP,GET请求,无参 GET http://httpbin.org/get Pyth ...
- fatal: 'origin' does not appear to be a git repository
git push时报以下错误: fatal: 'origin' does not appear to be a git repository fatal: Could not read from re ...
- Spring - 环境安装
安装IDEA的非Community版本和Java的包之后就可以用Java来HelloWorld了. 然后去这个链接:https://github.com/spring-guides/gs-rest-s ...
- Java 单例设计模式之 饿汉式和懒汉式
public class InstanceSampleTest { public static void main(String[] args) { /** 单例设计模式的 饿汉式和懒汉式 * 单例模 ...