Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与仅使用一个对象相比,使用多个不同对象进行锁定是否会对性能产生影响?_C#_.net_Multithreading - Fatal编程技术网

C# 与仅使用一个对象相比,使用多个不同对象进行锁定是否会对性能产生影响?

C# 与仅使用一个对象相比,使用多个不同对象进行锁定是否会对性能产生影响?,c#,.net,multithreading,C#,.net,Multithreading,我不知道这个问题是否愚蠢,锁定和显示器对我来说是一个黑匣子 但是我正在处理一种情况,我可以使用同一个lock对象来锁定所有的东西,或者使用不确定数量的对象来锁定更精细的粒度级别 我知道第二种方法将减少锁争用,但我可能最终使用10K对象作为锁,我不知道它是否有影响 一句话:锁太多会影响锁定还是没有影响 编辑 我写了一个维护对象图的库,这个数字可能非常高。现在它不是线程安全的,主要是因为Eric在评论中提到的原因 我最初认为,如果用户想要执行一些多线程,那么他/她就必须负责锁定 但是现在我想知道,如

我不知道这个问题是否愚蠢,锁定和显示器对我来说是一个黑匣子

但是我正在处理一种情况,我可以使用同一个lock对象来锁定所有的东西,或者使用不确定数量的对象来锁定更精细的粒度级别

我知道第二种方法将减少锁争用,但我可能最终使用10K对象作为锁,我不知道它是否有影响

一句话:锁太多会影响锁定还是没有影响

编辑

我写了一个维护对象图的库,这个数字可能非常高。现在它不是线程安全的,主要是因为Eric在评论中提到的原因

我最初认为,如果用户想要执行一些多线程,那么他/她就必须负责锁定

但是现在我想知道,如果我必须使它成为线程安全的,那么最好的方法是什么(注意,使它成为线程安全的对我来说不是一个简单的过程,所以测试这两个解决方案是我不容易做到的)

由于其目的是使图形的每个对象都是线程安全的,因此当我想要访问/修改其属性时,我可以使用对象的实例作为锁。我知道这是减少争用的最好方法,但我不知道它是否会像在整个图中只使用一个锁那样扩展


<>我知道有很多事情要考虑,有多少线程,尤其是(我认为)一个对象一次被多个线程访问/改变的机会(我估计是相当低的)。但是在这种情况下,我找不到关于锁及其开销的准确信息。

通常,关于锁的性能问题与争用有关。获取一个无争用的锁大约需要10秒的纳秒。争用是真正的性能杀手。正如您所指出的,拥有更多的锁(更高的锁粒度)可以通过减少争用来提高性能

拥有多个锁的缺点通常是锁管理必须更加复杂。如果执行一个操作需要多个锁,则出现死锁或livelock等资源不足问题的可能性会增加。适当的锁管理,例如强制执行锁获取命令,可以缓解这些问题


如果没有更多的细节,我可能会使用一个锁,因为实现更简单,并且可以密切监视应用程序的性能。具体来说,有一些与锁争用相关的.NET性能计数器,可以帮助诊断/检测与锁争用相关的性能问题。

与所有与性能相关的答案一样,这取决于具体情况。看看他的六个问题,你的问题的答案是什么?试试在你的情况下会发生什么

核心数量、争用、缓存等都很重要,所以看看在您的情况下会发生什么,事先真的不可能知道

对于未点击链接的用户让他们跑马

我在这里谈论的不是速度,而是应用程序运行一段时间后的性能。根据Monitor的说法,在.NET中实现是相当智能的,因此为每个对象设置内部锁似乎是一种可行的方法,因为您所说的对象有几万个,而不是几百万个

一句话:锁太多会影响锁定还是没有影响


这本身并不重要,但这可能是一个查看程序架构的原因,虽然同时有一个GASLLION对象会导致开销,但是

< P>为了更清楚地了解发生了什么,我在微软发布的共享源公共语言基础设施中,在代码> > CLR/SRC/VM/SycBLK.CPP</C>中查看了代码>监视程序<代码>类及其C++对应的源代码。 回答我自己的问题:不,有很多锁对我没有任何伤害

我学到的是:

1) 已被同一线程占用的锁被“几乎免费”处理

2) 第一次使用的锁基本上是
联锁比较交换的成本

3) 多个线程等待一个锁是相当便宜的跟踪(链接列表是维护的,O(1)复杂度)

4) 等待锁释放的线程是迄今为止最昂贵的用例,implem first spin会等待尝试退出,但如果不够,则会发生线程切换,将线程置于睡眠状态,直到互斥体发出信号,表示该因锁释放而唤醒

我通过挖掘得到了答案:2):如果您总是锁定同一个对象或10K不同的对象,那么基本上是一样的(第一次锁定给定对象时会执行额外的初始化,但这并不太糟糕)。InterlocatedCompareeExchange不关心在相同或不同的内存位置(AFAIK)上被调用

到目前为止,争论是最关键的问题。拥有多个锁将(在我的例子中)减少争用的机会,因此这只能是一件好事

1) 这也是一个重要的经验教训:如果我为每次属性更改/访问锁定/解锁,我可以通过先锁定对象,然后更改许多属性并释放锁来提高性能。这样,只有一个InterlocatedCompareeExchange,属性更改/访问实现中的锁定/解锁只会增加一个内部计数器


为了更深入地挖掘,我必须找到更多关于InterlocatedCompareeExchange实现的信息,我认为它依赖于CPU特定的汇编指令…

回答您问题的最佳方法是比较两种解决方案的性能。在一般情况下,没有办法说。它将是高度特定于上下文的。这将取决于多少钱