gpt4 book ai didi

c# - 什么时候应该使用每个线程同步对象?

转载 作者:行者123 更新时间:2023-11-30 14:20:49 24 4
gpt4 key购买 nike

在什么情况下应该使用以下各个同步对象?

  1. 读写锁
  2. 信号量
  3. 互斥体

最佳答案

  • 由于 wait() 将在每次调用 post() 时返回一次,因此信号量是一种基本的生产者-消费者模型 - 除了可能的信号之外,线程间消息的最简单形式。它们用于一个线程可以告诉另一个线程发生了它感兴趣的事情(以及多少次),并用于管理对最多具有固定有限数量用户的资源的访问。它们提供多线程代码所需的顺序保证。

  • 互斥锁做他们在锡 jar 上所说的 - “互斥”。它们确保访问某些资源的权利一次仅由线程“持有”。这保证了多线程代码所需的原子性和顺序。在大多数操作系统上,它们还提供相当复杂的服务员行为,特别是为了避免优先级倒置。

请注意,信号量可以很容易地用于实现互斥,但由于信号量没有“所有者线程”,因此您无法通过信号量避免优先级反转。因此它们并不适合所有需要“锁”的用途。

  • ReaderWriter 锁是对互斥体的优化,在您有很多争用的情况下,大多数访问都是只读的,并且允许同时读取 protected 数据结构。在这种情况下,仅当涉及作者时才需要排除——读者不需要相互排除。为了将读者提升为作者,所有其他读者必须在获取作者锁之前完成(如果他们也希望成为作者,则中止并开始等待重试)。 ReaderWriter 锁在速度不快的情况下可能会变慢,因为它们在互斥体上进行了额外的簿记。

  • 条件变量用于允许线程等待某些事实或事实组合为真,其中所讨论的条件比信号量的“它已被戳”或“没有其他人正在使用”更复杂它”用于互斥锁和读写器锁的写入器部分,或者“没有写入器正在使用它”用于读写器锁的读取器部分。它们还用于不同等待线程的触发条件不同但取决于部分或全部相同状态(内存位置或其他)的情况。

  • 自旋锁适用于当您在一个处理器或内核上等待很短的时间(例如几个周期),而另一个内核(或 I/O 总线等硬件)同时做一些你关心的工作。在某些情况下,它们比其他原语(例如信号量或中断)提供了性能增强,但必须格外小心(因为现代内存模型中的无锁算法很困难)并且只有在被证明有必要时才使用(因为避免系统原语的好主意通常是过早的优化)。

顺便说一句,这些答案不是特定于 C# 的(因此例如关于“大多数操作系统”的评论)。 Richard 提出了一个很好的观点,即在 C# 中,您应该在适当的地方使用普通的旧锁。我相信 Monitors 是组合到一个对象中的一对互斥锁/条件变量。

关于c# - 什么时候应该使用每个线程同步对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/760168/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com