什么是线程争用?

有人能简单解释一下什么是线程争用吗?

我谷歌了一下,但似乎找不到一个简单的解释。

71331 次浏览

本质上,线程争用是一种情况,其中一个线程正在等待当前由另一个线程持有的锁/对象。因此,此等待线程不能使用该对象,直到另一个线程已解锁该特定对象。

另一个词可能是并发性。这只是两个或多个线程试图使用同一资源的想法。

有两个线程,线程 A 和线程 B,还有对象 C。

A 当前正在访问对象 C,并在该对象上放置了一个锁。 B 需要访问对象 C,但是在 A 释放对象 C 的锁之前不能这样做。

来自 给你:

当线程是 等待一个不是 容易获得; 它减缓了 执行您的代码,但可以清除 随着时间的推移。

时发生死锁 等待第二个资源 线程已锁定,第二个 线程正在等待一个资源 第一个线程已锁定 两个线程可以包含在一个 僵局。僵局永远不会解决 它经常导致整个 应用程序,或部分是 经历僵局,停止。

有几个答案似乎集中在锁争用上,但是锁并不是可能发生争用的唯一资源。争用仅仅是当两个线程试图访问相同的资源或相关的资源时,其中至少一个争用的线程的运行速度比另一个线程不运行时要慢。

争用最明显的例子是在锁上。如果线程 A 有一个锁,而线程 B 想要获得同一个锁,那么线程 B 将不得不等待,直到线程 A 释放这个锁。

现在,这是特定于平台的,但是线程可能会遇到减速,即使它从不需要等待另一个线程释放锁!这是因为锁保护某种类型的数据,而且数据本身通常也会争用。

例如,假设一个线程获取一个锁,修改一个对象,然后释放这个锁并做一些其他的事情。如果两个线程都这样做,即使它们从不争夺锁,那么线程的运行速度可能会比只有一个线程运行时慢得多。

为什么?假设每个线程在现代的 x86 CPU 上运行在自己的内核上,而内核不共享 L2缓存。如果只有一个线程,那么对象大部分时间都会保留在 L2缓存中。在两个线程都运行时,每当一个线程修改对象时,另一个线程将发现数据不在其 L2缓存中,因为另一个 CPU 使缓存线路无效。例如,在奔腾 D 上,这将导致代码以 FSB 速度运行,这远低于 L2缓存速度。

因为即使锁本身没有争用,也可能发生争用,所以当没有锁时也可能发生争用。例如,假设您的 CPU 支持32位变量的原子增量。如果一个线程不断地递增和递减一个变量,那么该变量在大多数时候都会在缓存中处于热状态。如果两个线程这样做,它们的缓存将争夺持有该变量的内存的所有权,并且由于缓存一致性协议操作以保护缓存线路的每个核心所有权,许多访问将变慢。

具有讽刺意味的是,锁通常是 减少争用。为什么?因为如果没有锁,两个线程可能操作同一个对象或集合,并导致大量的争用(例如,存在无锁队列)。锁往往会取消争用线程的调度,而允许非争用线程运行。如果线程 A 持有一个锁,而线程 B 需要相同的锁,则实现可以运行线程 C。如果线程 C 不需要这个锁,那么线程 A 和线程 B 之间将来的争用可以暂时避免。(当然,这里假设还有其他线程可以运行。如果整个系统能够取得有用进展的唯一方法是运行具有竞争力的线程,那么这种方法将无济于事。)

对我来说,竞争是两个或更多线程之间对共享资源的竞争。资源可以是锁、计数器等。竞争意味着“谁先得到”。线程越多,争论越激烈。对资源的访问越频繁,争用就越多。

我认为 OP 应该对这个问题的背景做出一些澄清——我可以想到两个答案(尽管我确信这个列表中还有其他的答案) :

  1. 如果您指的是线程争用的一般“概念”以及它如何在应用程序中呈现自己,我推荐@DavidSchwartz 上面的详细答案。

  2. 还有“ .NET CLR 锁和线程: 争用的性能计数器总数 #”。根据 PerfMon 对此计数器的描述,它被定义为:

    此计数器显示 CLR 中线程试图获取托管锁失败的总次数。可以通过多种方式获取托管锁; 通过 C # 中的“ lock”语句或通过调用 System。监视器。输入或使用 MethodImpOptions。同步自定义属性。

我相信其他操作系统和应用程序框架。

线程争用也会受到 I/O 操作的影响。例如,等待文件读取的线程可以被视为争用。使用 I/O 完成端口作为解决方案。

锁争用发生在线程试图获取 已经被其他线程 * 获取的对象 被释放时,线程被阻塞(换句话说,它在 在某些情况下,这可能导致所谓的串行 对应用程序产生负面影响的执行。

DotTrace 文档

想象一下下面的场景,你正在为明天的决赛做准备 检查并感到有点饿。所以,你给你的弟弟 10美元,让他给你买个披萨。在这种情况下,你是 主线和你的兄弟是一个子线程。一旦你的命令 考虑到,你和你哥哥都在同时做他们的工作 (例如,学习和购买披萨)。现在,我们有两个案例 首先,你哥哥把你的披萨带回来,然后终止 当你在学习的时候。在这种情况下,你可以停止学习和享受 第二,你早点完成学业,然后睡觉(也就是说,你的 分配给今天的工作——为明天的期末考试学习——完成了) 当然,你不能睡觉,否则, 你就没机会吃披萨了,你要做的是 等你弟弟把披萨带回来。

正如在例子中一样,这两个案例给出了竞争的含义。