Lock Convoy(锁封护)


  [1]Lock Convoy是在多线程并发环境下由于锁的使用而引起的性能退化问题。当多个相同优先级的线程频繁地争抢同一个锁时可能会引起lock convoy问题,一般而言,lock convoy并不会像deadlock或livelock那样造成应用逻辑停止不前,相反地,遭受lock convoy的系统或应用程序仍然往前运行,但是,由于线程们频繁地争抢锁而导致过多的线程环境切换,从而使得系统的运行效率大为降低,而且,若存在同等优先级下不参与锁争抢的线程,则它们可以获得相对较多的处理器资源,从而造成系统调度的不公平性。
  Lock Convoy描述的是这样一种情况,假设有ABC三个线程在同一个时间片内多次取锁,在不考虑优先级的情况下(假设调度规则为平均时间),则可能发生当A执行1/3的时间片后被调度进程中断,转而执行B,B也执行了1/3的时间片后被调度进程中断,执行C。这样三个线程总是没执行完时间片就被打断。(在现代操作系统中,只要一个线程获取了一个时间片,那么在时间片内它就不能被重新执行),导致线程频繁切换,而降低系统的执行效率。

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

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

  一种合理的缓解lock convoy的方案,要求在每个线程获取锁的时候先尝试(try),如果尝试多次仍不成功,再阻塞。

 
Priority inversion(优先级反转)

  高优先级任务需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务的现象,叫做优先级反转。
  (注意: 此时高优先级任务和中等优先级任务之间没有任何共享资源但执行顺序却发生了倒置,这种情况才称为优先级反转;而高优先级任务因为等待低优先级任务释放资源而阻塞的情况则不称为优先级反转。)
 
  图片含义:当低优先级在运行时被高优先级打断,但高优先级所使用的资源被低优先级所占用而阻塞,此时中优先级打断低优先级任务,低优先级任务发生了阻塞,而此时高优先级和中优先级没有任何资源共享,却发生了优先级反转。
 
       两种经典的防止反转的方法:
        1. (Priority inheritance,优先级继承):继承现有被阻塞任务的最高优先级作为其优先级,任务退出临界区,恢复初始优先级。 在上述例子中当高优先级任务需要等待低优先级任务释放资源而阻塞时,就将低优先级任务的优先级升为高优先级任务的优先级,当它退出临界区后就将其优先级恢复为初始优先级。
        2. (Priority ceilings,设置优先级上限):设置优先级上限是指将申请(占有)某资源的任务的优先级提升到可能访问该资源的所有任务中最高优先级任务的优先级。如上面的例子,如果给低优先级线程抬高到最高优先级,那么中级优先级程序就不会被调度,不会发生优先级反转。
 
 
 
 

线程调度的问题:Lock Convoy(锁封护)与Priority Inversion(优先级反转)的更多相关文章

  1. [C#基础]说说lock到底锁谁?

    写在前面 最近一个月一直在弄文件传输组件,其中用到多线程的技术,但有的地方确实需要只能有一个线程来操作,如何才能保证只有一个线程呢?首先想到的就是锁的概念,最近在我们项目组中听的最多的也是锁谁,如何锁 ...

  2. Coarse-Grained lock 粗粒度锁

    用一个锁Lock一组相关的对象 有时,需要按组来修改多个对象. 这样,在需要锁住其中一个的时候,必须连带地将其他的对象都上锁. 为每一个对象都加上一个锁是很繁琐的. 粗粒度锁是覆盖多个对象的单个锁. ...

  3. Java 线程锁机制 -Synchronized Lock 互斥锁 读写锁

    (1)synchronized 是互斥锁: (2)ReentrantLock 顾名思义 :可重入锁 (3)ReadWriteLock :读写锁 读写锁特点: a)多个读者可以同时进行读b)写者必须互斥 ...

  4. JUC--Callable 以及Lock同步锁

    /** * 一.创建执行线程的方式三:实现Callable接口.相较于实现Runnable接口方式,方法可以有返回值,并且可以抛出异常 * 二.callable 需要FutureTask实现类的支持. ...

  5. C# 说说lock到底锁谁?(1)

    写在前面 最近一个月一直在弄文件传输组件,其中用到多线程的技术,但有的地方确实需要只能有一个线程来操作,如何才能保证只有一个线程呢?首先想到的就是锁的概念,最近在我们项目组中听的最多的也是锁谁,如何锁 ...

  6. C# 说说lock到底锁谁?(2)

    摘要 今天在园子里面有园友反馈关于[C#基础]说说lock到底锁谁?文章中lock(this)的问题.后来针对文章中的例子,仔细想了一下,确实不准确,才有了这篇文章的补充,已经对文章中的demo进行修 ...

  7. [C#基础]说说lock到底锁谁?(补充与修改)

    摘要 今天在园子里面有园友反馈关于[C#基础]说说lock到底锁谁?文章中lock(this)的问题.后来针对文章中的例子,仔细想了一下,确实不准确,才有了这篇文章的补充,已经对文章中的demo进行修 ...

  8. spin lock自旋锁 双链表操作(多线程安全)(Ring0)

    通过spin lock自旋锁 ,为每个链表都定义并初始化一个锁,在需要向该链表插入或移除节点时不使用前面介绍的普通函数,而是使用如下方法: ExInterlockedInsertHeadList(&a ...

  9. 多线程安全问题之Lock显示锁

    package com.hls.juc; import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.Reentr ...

随机推荐

  1. Codeforces 749C【模拟】

    FST的时候好像挂了挺多人的~ 其实思路没啥难的,就是更好地理解题意吧,1到n一直循环,直到没有人能vote,一个人能vote也能叉掉一个人,一个人被叉就不能vote,判谁赢. 其实我管vote干嘛, ...

  2. lightoj 1078【同余定理】

    题意: 给你一个n和一个数 digit ,问你最少需要多少个 digit 使得整除于n; 思路: 同余定理(a+b)%n=(a%n+b%n)%n; (m%n+m%n*10+m%n*100+m%n*10 ...

  3. HDU3279【水】

    思路: 求数组里的第三大: #include <bits/stdc++.h> using namespace std; typedef long long LL; int a[15]; i ...

  4. 浅谈C# String对象

    本文介绍C#中的string是一个引用类型,C# String对象是存放在堆上,而不是堆栈上的,因此,当把一个字符串变量赋给另一个字符串时,会得到对内存中同一个字符串的两个引用. AD:WOT2015 ...

  5. Codevs 1794 修剪花卉

    1794 修剪花卉   题目描述 Description ZZ对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题. 一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿 ...

  6. 洛谷P3306 [SDOI2013]随机数生成器(BSGS)

    传送门 感觉我BSGS都白学了……数学渣渣好像没有一道数学题能自己想出来…… 要求$X_{i+1}=aX_i+b\ (mod \ \ p)$ 左右同时加上$\frac{b}{a-1}$,把它变成等比数 ...

  7. c#file类读写

    private void button4_Click(object sender, EventArgs e) { FileStream fs = File.OpenRead(textBox1.Text ...

  8. zookeeper 搭建

    zookeeper 版本为zookeeper 3.4.8 操作系统为ubuntu 12.04 64位 zookeeper 单机搭建 解压zookeeper 包 .tar.gz -C /root/sof ...

  9. php-fpm 高并发 参数调整

    工作中经常会遇到会给客户配置服务器,其中有的客户还会有并发量要求,其中也会必须要用负载均衡承载压力的.增加服务器数量肯定能有效的提升服务器承载能力,但只有根据目前已有配置设置好单台服务器才能更好的发挥 ...

  10. 原来TextBox打开了MultiLine之后就不能使用AutoComplete了

    private void Form1_Load(object sender, EventArgs e) { // Create the list to use as the custom source ...