.NET:线程的开销

时间:2011-10-10 14:26:45

标签: .net multithreading performance marshalling

假设我有两个线程:A和B.当A创建一个对象(例如String的List)时,将其传递给B进行处理。每次B访问此对象时性能是否会降低?或者当物体从A到B编组时会有一次性惩罚吗?

3 个答案:

答案 0 :(得分:6)

.NET中的线程之间没有编组。两个线程将与相同的内存交互以与对象关联的存储。拥有一个线程而不是另一个线程对该对象执行操作没有性能开销。

您需要担心线程之间的同步,以确保线程安全,而不是性能。

答案 1 :(得分:3)

线程存在于同一个内存空间中,因此没有编组,也没有访问对象的惩罚。

但是,由于它们共享内存,因此您必须同步对对象的访问权限,以便任何一次更改的内容一次只能由一个线程访问。当一个线程正在访问一个对象时,另一个线程必须等待,这将导致一些开销。

答案 2 :(得分:2)

仅仅因为您在.Net中使用多个线程并不意味着将使用编组。当您在AppDomains之间共享对象时,Marshaling会发挥作用。

假设没有AppDomains,那么您支付的开销就是锁定 - 确保一次只有一个线程访问该对象。每次锁定和解锁对象时,都会占用一些CPU周期。

使用多个线程也可以添加其他惩罚 - 例如,如果您必须从线程A交换到线程B以完成某个任务,那么可能会有线程切换的惩罚。如果CPU必须将线程A放到床上并唤醒线程B,那么将花费一些处理器周期来完成此操作。即使线程A和线程B在不同的CPU上运行但是修改公共数据,也可能必须丢弃CPU高速缓存中的数据(高速缓存晃动)。只是警告您可以尝试通过并行处理来加快速度,但最终会降低您的应用速度。

如果您正在访问另一个.Net AppDomain中创建的对象,则将使用Marshaling。而且,根据您使用的编组类型,您可以选择一次性惩罚(按值进行编组)或每次调用惩罚(按参考编组)。