paper : 《Synchronization Primitives for a Multiprocessor: A Formal Specification》(1987)

原文下载:Synchronization Primitives for a Multiprocessor : A Formal Specification 本文给出了一组用于线程同步的原语,它们在DEV SRC线程包中被实现(Modula-2+语言):

  1. Mutex
  2. Condition
  3. Semaphore

首先是非形式化的描述,讲述每个原语的含义和用法; 然后是形式化描述,通过一种Latch Language来定义每个原语的语义; 最后简单介绍了每个原语在语言包中是如何实现的。 文章想告诉我们:同步原语是非常复杂和精妙的,如果不用形式化方法是难以说清楚的(虽然我觉得本文第一部分已经把原语的含义讲得很好了)。 从学术角度来说,要定义语义,需要用一些更基本的数学语言来描述,比如这里的Latch Language,比如常见的进程代数,Pai演算等。我现在已经不搞这些东西了,但是现在似乎真正有点了解这些东西的用途了。当初在学校学的时候非常机械,其实是完全不懂它们存在的意义与用法,比如Pai演算,呵呵,跑题了:) 这篇文章虽然是1987年的文章,但是里面对于这些原语的定义和语义已经是非常成熟了。我建议学习多线程程序设计的同学都可以看一下。里面还提到了为什么Condition这种原语,在发起等待,继而醒来后,需要再次验证一下predicate(谓词,也就是条件,非常优雅的说法)。一般都把这种苏醒认为是一个hint,不是一定获得了signal。在当初设计的时候,它们采用了一种高效的实现技术,叫做event count:

  • 每个条件变量c都关联一个单调递增的event count
  • 当线程1调用wait的时候,先记下当时的event count
  • 当线程2调用signal的时候,会增加这个event count
  • 线程1在做完其它工作,在真正进入睡眠等待之前,还要检查一次event count
    • 如果event count不变,则睡眠
    • 如果event count增加了,则直接唤醒
  • 而线程2执行signal会check条件变量关联的睡眠队列,唤醒里面的线程!
  • 所以,一下子有2个线程同时唤醒了!

很多年之后,我们的教材上依旧按照这个模式来教授Condition的用法,看样子内部实现原理没有太大的变化。 本文还教会了我关于二元信号量的用法(可能是唯一正确用法):中断处理routine与线程之间的同步。其它情况下,都推荐使用Mutex和Condition,国内的大牛陈硕也有类似论断。    

posted @ 2012-05-01 21:45  ohscar  阅读(168)  评论(0编辑  收藏  举报