.NET线程 - 锁需要的是任务 [英] .NET Threading - is lock needed for assignments

查看:124
本文介绍了.NET线程 - 锁需要的是任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些多线程code,我想增加一点的服务表现,所以我想知道如果我能摆脱锁。

I've got some multi threaded code I'd like to increase the performace of a bit, so I'm wondering if I can get rid of a lock.

我有一个字段成员:<​​/ P>

I've got a field member:

private IList<ServerStatus> status;

这在像这样一个线程更新:

It's updated in a thread like so:

status = GetUpdatedStatus();

和它在这样另一个线程使用的:

And it's used in another thread like this:

var currentStatus = status;

所以,问题是,上述收益率不锁绕两个赋值语句有问题?

So the question is, can the above yield any problems without locks around the two assignment statements ?

我想我可以看到的是currentStatus被空的唯一方案,但话又说回来,我期望的分配是有点线​​程安全的(无论是它改变了参考或不)

I guess the only scenario I can see is currentStatus being null, but then again I'd expect an assignment to be somewhat thread-safe (either it has changed the reference or not)

推荐答案

你是对的。您将看到分配,否则将无法看到它。分配引用(并读取)始终是原子(到底是因为在32位机器引用是32位的,所以可以自动完成,并在64位机器(运行64位应用程序)引用是64位,因此可以自动完成的,唯一的例外是试图写入/ 32位机器上读长(64位)。在那里,你将不得不使用Interlocked.Read / Interlocked.Exchange)

You are right. You will see the assignment or you won't see it. Assignments (and reads) of references are always "atomic" (in the end it's because on 32 bits machines references are 32 bits, so can be done atomically, and on 64 bits machines (running a 64 bits app) references are 64 bits, so can be done atomically. The only exception is trying to write/read a long (64 bits) on a 32 bits machine. There you would have to use Interlocked.Read / Interlocked.Exchange)

的应申报地位挥发性,使每个线程只能看到最新版本。你应该阅读: http://www.albahari.com/threading/ 这是非常非常好的。

Normally should declare status as volatile, so that each thread sees only the latest version. You should read this: http://www.albahari.com/threading/ it's very very good!

如果你不相信我,请阅读第,我们真的需要锁和障碍?此处<一个href="http://www.albahari.com/threading/part4.aspx">http://www.albahari.com/threading/part4.aspx

If you don't trust me, read the section Do We Really Need Locks and Barriers? here http://www.albahari.com/threading/part4.aspx

嗯......我忘了......世界就恨你,所以有一点是要知道的挥发性:有时不读:-) :-)工作,在其他的同一页例如,部分 volatile关键字,在红色框的部分。 注意,将挥发性不prevent写随后被换读,这样就可以创建脑筋急转弯。最后,可以肯定的唯一方式是使用 Interlocked.Exchange 来编写和 Interlocked.CompareExchange 阅读东西或保护读取和写入部分与同步(如锁定),或与Thread.MemoryBarrier填写你的程序(但不要尝试它,你就会失败,你甚至不知道为什么)。这样保证了所有的读取和锁进行写操作将完成在锁,而不是之前或之后。

Ah... I was forgetting... The world HATES you, so there is a little thing to know of volatile: sometimes it doesn't work :-) :-) Read, in the same page of the other example, the section The volatile keyword, the part UNDER the red box. Notice that applying volatile doesn’t prevent a write followed by a read from being swapped, and this can create brainteasers. In the end, the only way to be sure is to use Interlocked.Exchange to write and Interlocked.CompareExchange to read something OR protect the read and the write sections with synchronization (like lock) OR fill your program with Thread.MemoryBarrier (but don't try it, you'll fail, and you won't even know why). You are guaranteed that all the reads and the writes done in the lock will be done IN the lock, not before or after.

这篇关于.NET线程 - 锁需要的是任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆