Ste*_*fen 12 .net c# multithreading locking
我有一些多线程代码,我想增加一点的性能,所以我想知道我是否可以摆脱锁.
我有一个现场成员:
private IList<ServerStatus> status;
Run Code Online (Sandbox Code Playgroud)
它在这样的线程中更新:
status = GetUpdatedStatus();
Run Code Online (Sandbox Code Playgroud)
它在另一个线程中使用,如下所示:
var currentStatus = status;
Run Code Online (Sandbox Code Playgroud)
所以问题是,如果没有锁定两个赋值语句,上面会产生任何问题吗?
我想我能看到的唯一情况是currentStatus为null,但是我再次希望赋值有点线程安全(或者它已经更改了引用)
xan*_*tos 20
你是对的.您将看到作业,否则您将看不到它.引用的赋值(和读取)总是"原子的"(最后它是因为32位机器引用是32位,所以可以原子方式完成,而64位机器(运行64位应用程序)引用是64位,所以可以原子方式完成.唯一的例外是尝试在32位机器上写/读长(64位).你必须使用Interlocked.Read/Interlocked.Exchange)
通常应将状态声明为volatile,以便每个线程只能看到最新版本.你应该读到这个:http://www.albahari.com/threading/它非常好!
如果你不相信我,请阅读节Do We Really Need Locks and Barriers?在这里http://www.albahari.com/threading/part4.aspx
嗯......我忘了......世界就恨你们,所以知道的挥发性小东西:有时它不:-) :-)阅读工作,在其他例子的同一页中,部分The volatile keyword,红色框下的部分.Notice that applying volatile doesn’t prevent a write followed by a read from being swapped, and this can create brainteasers.最后,唯一可以确定的方法是使用Interlocked.Exchange写入和Interlocked.CompareExchange读取内容,或者使用同步保护读取和写入部分(例如lock)或者用Thread.MemoryBarrier填充程序(但不要尝试,你要'会失败,你甚至不知道为什么).保证锁定中的所有读取和写入都将在锁定中完成,而不是在锁定之前或之后.
参考写入是原子保证的,因此只需要检查两件事:
volatile如果需要注意更改,可能需要添加Interlocked.CompareExchange以确保不丢失数据; 继续重新应用您的更改,直到您赢得交换即
object snapshot, newValue;
do
{
snapshot = field;
// do something based on that; create a clone
// with more/less data for example
newValue = ...;
} while (!ReferenceEquals(
Interlocked.CompareExchange(ref field, newValue, snapshot), snapshot));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2347 次 |
| 最近记录: |