Concurrency 静态互斥分析

Concurrency 静态互斥分析,concurrency,mutex,language-design,Concurrency,Mutex,Language Design,有一种静态检查互斥正确性的语言明智吗?即 var m var x guarded_by(m) func f1() { lock(m) x = 42 unlock(m) } func f2() { x = 42 // error, accessing x w/o holding its mutex } func f3() assumes_locked(m) { x = 42 } func b1() { f3() // error } func b2() {

有一种静态检查互斥正确性的语言明智吗?即

var m
var x guarded_by(m)

func f1() {
  lock(m)
  x = 42
  unlock(m)
}

func f2() {
  x = 42  // error, accessing x w/o holding its mutex
}

func f3() assumes_locked(m) {
  x = 42
}

func b1() {
  f3()  // error
}

func b2() {
  lock(m)
  f3()
  unlock(m)
}
  • 这可能吗?也就是说,可以用几个简单的注释静态验证互斥使用的正确性吗
  • 这是否合理?这是个坏主意,有什么原因吗
  • 是否有任何语言具有此内置功能
  • 静态竞争条件检测 ,“互斥正确性”可以指很多事情,听起来你在谈论种族状况检测,这对我来说很方便,因为这是我本科论文的主题:-)你想知道(1)这是否可能,(2)这是否合理,以及(3)这是否完成。与任何静态分析一样(包括轻量级类型或效果系统——比如这样的系统),前两个问题归结为四件事:

  • 可靠性:是否允许任何不正确的程序?如果是,有多少/哪些
  • 完整性:是否排除了任何正确的程序?如果是,有多少/哪些
  • 可用性:程序员的开销如何?例如,需要什么注释,错误消息是否可理解等
  • 目标:在由上述三个约束限定的设计空间中,我们试图在哪里结束
  • 请注意,由于停止问题(及其更普遍的大兄弟),我们永远无法获得1和2的100%准确度。例如,大多数类型系统都以可靠性和可用性为目标(#1和#3);也就是说,它们的目标是易于使用,同时不允许类型不安全的程序,并试图排除不现实的类型安全程序。(他们的拥护者和我一样,会声称他们在这一目标上大体上取得了成功。)

    一个简单的锁检查类型系统:RaceFreeJava 您的示例似乎试图最大限度地提高可用性(#3):您提供了最小的注释,这与您希望程序员记住的内容一致,然后需要进行分析以检查它们。整体方案听起来与之非常相似。RaceFreeJava是Java的一个扩展,其中:

    • 类可以通过锁参数化(称为
      ghost
      locks)
    • 字段可以通过指定必须保护它们的锁的注释进行保护;及
    • 方法可以有
      需要
      注释,指定调用它们必须持有哪些锁
    正如您可能猜测的那样,这个想法是每个字段都有一个关联的锁,每次访问该字段时都必须持有该锁;分析跟踪在每个程序点持有的锁,如果在变量的锁不在当前锁集中时访问该变量,则会报告错误。使用
    ghost
    lock参数,这会变得稍微微妙一些;例如,你可以

    类运行总计{
    私有整数和=0,由m保护;
    私有int乘积=1,由m保护;
    公共void include(int x)需要m{
    总和+=x;
    乘积*=x;
    }
    public int getSum()需要m{
    回报金额;
    }
    public int getProduct()需要m{
    退货产品;
    }
    }
    
    现在我可以将
    RunningTotals
    对象嵌入到其他对象
    o
    中,并使用
    o
    的锁保护它,这很方便;但是,分析时需要注意哪个锁
    m
    。另外,请注意,
    RunningTotals
    中的方法无法在
    m
    上同步,因为
    m
    不在范围内,只是类型级别的
    ghost
    ;同步必须由客户端处理。与我们如何声明锁参数化类类似,RaceFreeJava的另一个特性是能够声明
    thread\u local
    类;这些类永远不允许在线程之间共享,因此不需要用锁保护它们的字段

    正如您在一篇评论中所指出的,判断一个程序使用这些注释是否正确通常是不可确定的,特别是因为Java允许您对任意表达式进行同步。为了理智起见,RaceFreeJava将同步限制在最终表达式上;然后,就像所有类似类型的注释一样,它对锁标识使用保守的语法检查。Abadi等人发现,大多数正确的程序都可以通过这种方式成功地进行检查。因此,他们以牺牲完整性为代价,强烈地依赖于可靠性(事实上,分析是声音模块化他们放入的一些逃生舱口)和可用性。为了检查可用性——这与完整性密切相关,因为过多的虚假警告使静态分析几乎不可用——Abadi等人还编写了一个工具(
    rccjava
    ),用于检查这些注释并进行少量注释推断,还用它构建了一个更大的工具(
    Houdini/rcc
    )进行更多的推理。在评估这些(表I-IV)时,他们发现了真正的bug,没有太多必要的注释或虚假的警告。但是,请注意,它并不完美;本分析将抱怨一些有效的Java程序

    其他静态种族检测器 因为我天生喜欢长篇大论,而且(正如我提到的)我写了关于这一点的本科论文,我还将讨论其他一些分析,但在我看来,RaceFreeJava可能是最相关的。如果你想直接跳到最后,这一节后面有一个总结

    另一种基于系统的分析是由。这种类型的系统检测竞争条件和死锁,但使用不同的技术;它基于所有权类型,跟踪允许哪些线程访问哪些变量;只有在拥有变量所有者的锁时,才能访问变量。同样,方法可以注释所需的
    访问
    或所需的
    。为了检查死锁,Boyapati等人