Lock Convoys Explained

潘爱民,2010-10-9

Lock Convoys是在多线程并发环境下由于锁的使用而引起的性能退化问题。当多个相同优先级的线程频繁地争抢同一个锁时可能会引起lock convoys问题,一般而言,lock convoys并不会像deadlock或livelock那样造成应用逻辑停止不前,相反地,遭受lock convoys的系统或应用程序仍然往前运行,但是,由于线程们频繁地争抢锁而导致过多的线程环境切换,从而使得系统的运行效率大为降低,而且,若存在同等优先级下不参与锁争抢的线程,则它们可以获得相对较多的处理器资源,从而造成系统调度的不公平性。

本文将解释lock convoys问题的缘由。

假设一组线程在频繁地获取锁(所谓频繁,指在一个时间片的执行周期内多次获取锁),比如在Windows应用程序中常常用临界区(critical section)来保护一个共享变量或者防止一段代码被重入,这是极有可能发生的。假设线程A获取到了锁,这时发生了线程调度中断,它的时间片用完了,于是,系统调度器交给下一个线程执行,不妨设线程B获得了执行权。由于此锁被线程A获取,所以,当线程B执行到获取锁的操作时,虽然时间片未用完,但不得不放弃执行权。如此继续,所有同等优先级且要竞争此锁的线程都被阻塞。调度器再次回到线程A,很快地线程A释放了锁。在操作系统中,释放一个锁,意味着内核中如果有线程正在等待该锁,则它的状态就可以变成运行态。比如,线程B的获取操作成功。但此时,内核只是将线程B标记为锁的所有者,而线程A继续执行。很快地,线程A又要获取锁了,由于该锁已经被标记给线程B了,所以线程A不得不放弃时间片,将控制权交给调度器。调度器终于可以捡起线程B,将处理器的执行权交给它。等到线程B释放了锁,下一个线程获得锁的所有权,并且等到线程B放弃执行权或者结束时间片之后就有机会被执行。此过程一直持续,经过一轮之后又会回到线程A,从而继续下一轮的争抢。在此期间,这些线程总是未执行满时间片就不得不放弃执行权。下面的图说明了三个线程在争抢一个锁时候的执行情况。

假设一个线程在一个满时间片的执行过程中要多次获取/释放锁,它一旦释放了锁,则意味着,只要存在锁竞争,它在分配给它的当前时间片内已经无法再重新获得锁了。所以,它只能执行到它的下一次获取操作为止。譬如,参与竞争的线程平均执行1/3时间片就要获取锁,那么,线程的实际执行时间变成了1/3时间片。系统的调度粒度变成原来的1/3时间间隔。这引起了3倍数量的线程切换。从上图的右半部分可以看出,每个线程在一轮的循环中,只有1/3时间片的机会。这导致了3倍的线程切换。

除了引起调度粒度变小以外,lock convoys的另一个问题是造成调度器的时间分配不公平。假设另有一个线程X也是在同等的优先级上运行,但没有参与锁竞争。于是,在每一轮的锁竞争过程中,线程X都有机会被分配一次完整的时间片,于是,这些竞争的线程在一轮中获得1/3时间片,而非竞争的线程可以获得完整的时间片。当然,你可以说这种不公平是由于它们抢锁而引起的,但从时间分配比例而言,参与竞争与不参与竞争的线程是不公平的。下图说明了线程X和A、B、C之间的执行时间差异。

由以上描述可以看出,Lock convoys的存在条件是,参与竞争的线程频繁地获取锁,锁被一个线程释放以后其所有权便落到了另一个线程的手里。在操作系统中,相同优先级的线程按照FIFO的顺序被调度和执行,竞争同一个锁的线程也按照FIFO的顺序被依次成功地获取到锁。这些条件在现代操作系统中都能被满足,包括Windows。

Lock convoys虽然不是致命的问题,但也可能在实际系统中发生。Sue Loh在她的博客文章[1]中展示了在Windows CE中发生的lock convoy问题。她也讨论了一种合理的缓解lock convoy的方案,要求在每个线程获取锁的时候先尝试(try),如果尝试多次仍不成功,再阻塞。

注1:关于lock convoys的介绍资料非常少,在wikipedia上也只有极有限的说明[2],Sue Loh的博客文章[1]有比较详细的说明。我计划在下一篇文章中再讨论lock convoys问题在Windows平台上的表现(以Windows Server 2003 SP1和WRK作为参照)以及线程执行路径。

注2:关于lock convoys的中文翻译,我看到有一本书上将其翻译为“锁护送”。个人感觉不是非常妥当,或许翻译为“锁封护”或“锁护封”好一些。

References:

[1] Sue Loh, Lock Convoys and How to Recognize Them, http://blogs.msdn.com/b/sloh/archive/2005/05/27/lock-convoys-and-how-to-recognize-them.aspx, 2005.

[2] Lock Convoys, http://en.wikipedia.org/wiki/Lock_convoy

Lock Convoys Explained相关推荐

  1. 并发危险:解决多线程代码中的 11 个常见的问题

    本文将介绍以下内容: 基本并发概念 并发问题和抑制措施 实现安全性的模式 横切概念 本文使用了以下技术:  多线程..NET Framework 目录 数据争用  忘记同步  粒度错误  读写撕裂  ...

  2. oracle授权v$lock,访问V$LOCK视图Oracle 11g出现性能问题

    最近发现Oracle 11g有个问题,拿出来和大家讨论.是在Oracle 11.2.0.3 For Linux X64环境中.检查数据库是否存在锁信息,在查询V 最近发现Oracle11g有个问题,拿 ...

  3. 05.抽象队列同步器AQS应用之Lock详解

    AQS应用之Lock Java并发编程核心在于java.concurrent.util包而juc当中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列.条件队列.独占获取.共享获取等,而这个行为 ...

  4. 如何在Schlage Connect Smart Lock上启用警报

    The Schlage Connect smart lock includes a built-in alarm system that can deter any potential thieves ...

  5. 【java线程】锁机制:synchronized、Lock、Condition

    [Java线程]锁机制:synchronized.Lock.Condition 原创 2013年08月14日 17:15:55 标签:Java /多线程 74967 http://www.infoq. ...

  6. c# lock (obj) 与 lock (this) 区别

    lock(obj) 锁定 obj 对象 lock(this) 锁定 当前实例对象,如果有多个类实例的话,lock锁定的只是当前类实例,对其它类实例无影响. 直接上代码. 主窗体代码如下: delega ...

  7. java连接mysql执行ddl_Mysql 执行DDL导致Waiting for table metadata lock

    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...

  8. Go 分布式学习利器(18)-- Go并发编程之lock+WaitGroup实现线程安全

    Go语言中通过Groutine 启动一个Go协程,不同协程之间是并发执行的,就像C++/Java中线程之间线程安全是一个常见的问题. 如下Go 语言代码: func TestConcurrent(t ...

  9. apt Could not get lock /var/lib/dpkg/lock 解决方案

    apt Could not get lock /var/lib/dpkg/lock 解决方案 删除锁定文件 sudo rm /var/lib/dpkg/lock

最新文章

  1. 按功能顺序列出的 HTML 4.01/XHTML 1.0
  2. [转]一文解释PyTorch求导相关 (backward, autograd.grad)
  3. 是可改写的随机存储器_关于存储器的一些基础知识整理
  4. druid seata 配置_架构设计 | 基于Seata中间件,微服务模式下事务管理
  5. AngularJS 监控对象属性:$watch和$digest
  6. ios 关于自定义navigationItem,实现右侧多个按钮
  7. kafka 不同分区文件存储_Kafka 系列(二)文件存储机制与Producer架构原理怎样保证数据可靠性??...
  8. Windows 配置libjpeg-turbo并在python中调用
  9. 老毛桃官方网站linux,老毛桃 Ubuntu
  10. 巧用 Automator,为 Mac 创建自定义右键菜单
  11. 我需要HCNE模拟考试系统
  12. Elasticsearch:Elasticsearch 开发入门 - Golang
  13. spilt的用法小结
  14. usb热插拔多次之后无法识别
  15. 利用python提取图像轮廓
  16. 三、kylin读写分离集群部署
  17. ts版axios二次封装
  18. 换电脑了大量数据如何迁移?
  19. webdav服务器文件大小限制,WebDAV服务器
  20. 6.Jenkins-代码更新Jenkins自动发布项目

热门文章

  1. 透明、无窗口的Flash
  2. 聘请UX设计人员之前应了解的知识
  3. 【转】KK:科技发展的六个趋势
  4. JS alert确定删除 取消删除 配合 href
  5. 学校计算机教室工作简报,实验室、图书室、微机室三个管理平台使用情况网上检查简报...
  6. android中进程和线程的关系与区别
  7. java中的锁---乐观锁与悲观锁的区别
  8. Python编程:从入门到实践第五章练习题
  9. aes算法cbc模式c语言,AES算法及它的CBC加密模式
  10. 带领新手快速开发Android App