有人可以简单解释一下线程争用是什么吗?
我用谷歌搜索过,但似乎找不到简单的解释。
答案 0 :(得分:159)
几个答案似乎都集中在锁争用上,但锁并不是唯一可以经历争用的资源。争用只是当两个线程试图访问相同的资源或相关资源时,至少有一个竞争线程比其他线程没有运行时运行速度慢。
最明显的争用示例是锁定。如果线程A有锁并且线程B想要获取相同的锁,则线程B必须等到线程A释放锁。
现在,这是特定于平台的,但是线程可能会遇到速度减慢,即使它永远不必等待另一个线程释放锁定!这是因为锁可以保护某种数据,并且数据本身通常也会被争用。
例如,考虑获取锁定的线程,修改对象,然后释放锁定并执行其他操作。如果两个线程正在执行此操作,即使它们从不争取锁定,线程也可能比只运行一个线程时运行速度慢得多。
为什么呢?假设每个线程在现代x86 CPU上运行在其自己的核心上,并且核心不共享L2缓存。只有一个线程,对象可能在大多数时间保留在L2缓存中。在两个线程都在运行时,每次一个线程修改对象时,另一个线程将发现数据不在其L2缓存中,因为另一个CPU使缓存线无效。例如,在Pentium D上,这将导致代码以FSB速度运行,这远低于L2缓存速度。
由于即使锁本身不会争用也会发生争用,因此在没有锁定时也会发生争用。例如,假设您的CPU支持32位变量的原子增量。如果一个线程继续递增和递减变量,则该变量在大多数情况下将在缓存中变热。如果两个线程执行它,它们的缓存将争用拥有该变量的内存的所有权,并且许多访问将变慢,因为缓存一致性协议操作以保护缓存线的每个核心所有权。
具有讽刺意味的是,锁通常会减少争用。为什么?因为没有锁,两个线程可以对同一个对象或集合进行操作并导致大量争用(例如,有无锁队列)。锁定将倾向于取消竞争线程,允许非竞争线程运行。如果线程A持有锁并且线程B想要相同的锁,则实现可以运行线程C.如果线程C不需要该锁定,则可以在一段时间内避免线程A和B之间的未来争用。 (当然,这假设还有其他线程可以运行。如果系统作为一个整体能够取得有用进展的唯一方法是通过运行竞争的线程,那将无济于事。)
答案 1 :(得分:66)
基本上,线程争用是一个线程正在等待另一个线程当前持有的锁/对象的情况。因此,在另一个线程解锁该特定对象之前,此等待线程无法使用该对象。
答案 2 :(得分:18)
来自here:
线程发生争用 等待没有的资源 一应俱全;它减慢了 执行你的代码,但可以清除 随着时间的推移。
线程出现死锁 等待一秒钟的资源 线程已锁定,第二个 线程正在等待资源 第一个线程已锁定。多于 两个线程可以参与一个 僵局。死锁永远无法解决 本身。它经常导致整体 应用程序或部分 经历僵局,停下来。
答案 3 :(得分:3)
我认为OP应该在问题的背景上做一些澄清 - 我可以想到2个答案(尽管我确定此列表中还有其他内容):
如果你指的是一般概念"线程争用以及它如何在应用程序中呈现自己,我推迟到@ DavidSchwartz上面的详细解答。
还有“.NET CLR锁和线程:争用的总数'表现计数器。从该计数器的PerfMon描述中可以看出,它被定义为:
此计数器显示CLR中的线程尝试获取托管锁失败的总次数。管理锁可以通过多种方式获得;通过"锁定" C#中的语句,或者通过调用System.Monitor.Enter或使用MethodImplOptions.Synchronized自定义属性。
......我确信其他操作系统和应用程序框架。
答案 4 :(得分:2)
你有2个主题。线程A和线程B,你也有对象C。
A当前正在访问对象C,并锁定了该对象。 B需要访问对象C,但是在A释放对象C的锁之前不能这样做。
答案 5 :(得分:1)
另一个词可能是并发。这只是两个或多个线程试图使用相同资源的想法。
答案 6 :(得分:1)
对我而言,争用是共享资源上2个或更多线程之间的竞争。资源可以是锁,柜台等。竞争意味着“谁先得到它”。线程越多,争用越多。频繁访问资源的争用越多。
答案 7 :(得分:1)
想象一下以下场景。你正准备明天的决赛 检查并感到有点饿。所以,你给你的弟弟 十块钱,请他为你买一个披萨。在这种情况下,你是 主线程和你的兄弟是一个子线程。一旦你的订单 鉴于,你和你的兄弟同时兼顾他们的工作 (即学习和购买披萨)。现在,我们有两个案例 考虑。首先,你的兄弟带回你的披萨并终止 在你学习的同时在这种情况下,你可以停止学习和享受 比萨饼。其次,你提前完成学业并睡觉(即你的 为今天分配的工作 - 明天的期末考试 - 完成了) 在比萨饼可用之前。当然,你无法入睡;除此以外, 你没有机会吃披萨。你要做的是 等到你哥哥带回披萨。
如同在例子中,这两个案例给出了竞争的意义。
答案 8 :(得分:0)
线程争用也会受到I / O操作的影响。线程等待文件读取时的示例可以视为争用。使用I / O完成端口作为解决方案。
答案 9 :(得分:0)
当线程尝试获取锁定时,会发生锁争用 已被其他线程*获取的对象。直到对象 被释放,线程被阻止(换句话说,它在 等待状态)。在某些情况下,这可能会导致所谓的连续剧 执行会对申请产生负面影响。