【问题标题】:Does lock, Monitor, Mutex waste CPU cycles like SpinWait?lock、Monitor、Mutex 会像 SpinWait 一样浪费 CPU 周期吗?
【发布时间】:2020-07-09 05:24:55
【问题描述】:

最近我开始在 C# 中使用任务并行库学习并行编程,我读到 SpinLock 会浪费 CPU 周期并一直旋转直到获得锁为止。另外在比较方法时: Thread.Sleep 和 Thread.SpinUntil 我发现 Thread.sleep 释放调度程序,以便调度程序可以调度其他线程。 这对锁、监视器、互斥锁和互锁也适用吗? CLR 是否允许调度程序在 lock、Monitor、Mutex、Interlocked 等待进入临界区时调度其他线程?

【问题讨论】:

  • “发布调度程序” 不是一个东西。 “CLR 是否允许调度程序调度其他线程...”是的。然而,回答这个问题非常困难,因为术语的使用不寻常,而且很难理解您实际在问什么或为什么

标签: c# .net multithreading parallel-processing synchronization


【解决方案1】:

很难理解你的问题。我是这样尝试的:

  • SpinLock 很特别,因为它会执行“忙等待”。仅在您知道线程将等待很短的时间时使用,例如一些 CPU 周期。
  • lock、Monitor 和 Mutex 不忙等待。这些是线程同步的常规和最常用的方法。
  • Interlocked 根本不锁定。它用于所谓的“无锁同步”,这很棘手,应该很少使用。

我不知道您所说的调度程序是什么意思。线程一直在运行,直到它们以某种方式被锁定。只有一个线程可以获得相同的锁。当您创建自己的线程时,它们由操作系统(AFAIK)调度。当您使用线程池时,它们会被安排在那里。

【讨论】:

  • 调度程序意味着在等待时为线程池中的其他线程提供服务,例如我有 3 个线程,一个线程正在执行锁的关键部分,所以它已经获得了锁....现在线程 2 也想要执行代码的关键部分,但必须等待,因为代码当前在线程 1 下.....现在我的问题是:因为线程 2 正在等待进入临界区。 cpu 会处理线程 3,或者简而言之,它将上下文切换到线程 3,或者就像自旋锁一样一直等待直到线程释放锁......
  • 线程不会保持核心忙碌,除了 SpinLock。
  • 当您使用线程池并且线程数量有限时,您可能会遇到问题。当达到最大线程数时,不再创建线程,即使所有线程都在等待。所以线程不会让 CPU 核心保持忙碌,但它们可能会占用线程池中的线程,但线程数量有限。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-07
  • 2019-11-05
  • 1970-01-01
  • 2011-09-27
  • 2016-06-27
  • 1970-01-01
  • 2012-01-25
相关资源
最近更新 更多