在什么情况下应该使用以下每个同步对象? ReaderWriter锁定 信号量 Mutex 因为每次调用post()时wait()都会返回一次,所以信号量是一个基本的生产者 – 消费者模型 – 除了信号之外最简单的
> ReaderWriter锁定
>信号量
> Mutex
>互斥体做他们在锡上所说的话 – “相互排斥”.它们确保访问某些资源的权限一次只能在线程上“保留”.这样可以保证多线程代码所需的原子性和排序.在大多数操作系统中,它们还提供相当复杂的服务员行为,特别是为了避免优先级倒置.
请注意,信号量可以很容易地用于实现互斥,但由于信号量没有“所有者线程”,因此您不会使用信号量获得优先级倒置.因此它们不适合所有需要“锁定”的用途.
> ReaderWriter锁是对互斥锁的优化,如果您有很多争用,大多数访问都是只读的,并且允许同时读取受保护的数据结构.在这种情况下,只有在涉及作者时才需要排除 – 读者不需要彼此排除.为了促进读者写作,所有其他读者必须在获得作者锁之前完成(或中止并开始等待他们也希望成为作者时重试).在没有更快的情况下,ReaderWriter锁可能会更慢,因为它们会通过互斥锁进行额外的簿记.
>条件变量用于允许线程等待某些事实或事实组合为真,其中所讨论的条件比信号量的“已被戳”更复杂,或者“没有其他人使用它”用于互斥量和读写器锁的作者部分,或者“没有作者正在使用它”作为读写器锁的读者部分.它们也用于不同等待线程的触发条件不同的情况,但取决于部分或全部相同的状态(存储器位置或其他).
>旋转锁用于在一个处理器或内核上等待很短的时间(如几个周期),而另一个内核(或I / O总线等硬件)同时执行某些工作关心.在某些情况下,它们比其他原语(如信号量或中断)提供性能增强,但必须非常谨慎地使用(因为现代内存模型中的无锁算法很困难)并且只有在证明有必要时才会使用(因为明智的想法可以避免使用系统原语)往往是过早的优化).
顺便说一句,这些答案不是C#特定的(因此例如关于“大多数操作系统”的评论).理查德提出了一个很好的观点,即在C#中你应该使用普通的旧锁.我相信监视器是一个互斥/条件变量对卷入一个对象.