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 ...
随机推荐
- Java8新特性--CompletableFuture
并发与并行 Java 5并发库主要关注于异步任务的处理,它采用了这样一种模式,producer线程创建任务并且利用阻塞队列将其传递给任务的consumer.这种模型在Java 7和8中进一步发展,并且 ...
- springboot2.0整合shiro遇到的问题
1.重启服务器,访问登陆页面,登陆成功后跳转的不是index,而是favicon.ico
- JavaScript 廖2
HTML表单的输入控件主要有以下几种: 文本框,对应的<input type="text">,用于输入文本: 口令框,对应的<input type="p ...
- [Angular 8] Custom Route Preloading with ngx-quicklink and Angular
In a previous lesson we learned about implementing a custom preloading strategy. That gives you a lo ...
- 洛谷 P1076 寻宝 题解
今天又TM考试了...... 这是T1,然后我模拟20分滚粗. Analysis 在每层的时候用编号%这层可以上楼的房间个数就行了. #include<iostream> #include ...
- 062_判断用户输入的是 Yes 或 NO
#!/bin/bashread -p "Are you sure?[y/n]:" surecase $sure iny|Y|Yes|YES) echo "you ...
- luogu 4211
题意 存在一棵树,每次询问 \(l, r, z\) 求 \[\sum_{i = l} ^ {r} deep(lca(i, z))\] 考虑 lca 的实质:两点到根的路径的交集中深度最大的点 其中一点 ...
- (转)supervisor
转载:https://www.cnblogs.com/zhoujinyi/p/6073705.html 进程管理supervisor的简单说明 背景: 项目中遇到有些脚本需要通过后台进程运行,保证不被 ...
- docker 搭建registry
Docke官方提供了Docker Hub网站来作为一个公开的集中仓库.然而,本地访问Docker Hub速度往往很慢,并且很多时候我们需要一个本地的私有仓库只供网内使用.Docker仓库实际上提供两方 ...
- 如何在虚拟机中安装kali linux
整理笔记,把以前印象笔记中记录的一些东西翻出来,想想发个随笔吧. 第一步在官网下载kali linux的镜像. 网址:https://www.kali.org/downloads/ (我的电脑是64位 ...