当涉及高速网络消息传递时,使用易失性字典是一个不错的选择吗?
c#
前提
我正在开发一个多人游戏,我有许多网络控制的演员,我决定将女巫的输入存储在一个易变的字典中:
public static volatile Dictionary<string, QuickMessage> quickPlayerMessages;
并且每一帧演员都从该字典中获取他们的值,但与此无关,我还有一个接收器线程不断更新该字典,因此值会不断更改,并且键可能会被删除或添加到其中。我做了一些测试,这有效,但是......
我的顾虑
我不完全理解 volatile 修饰符,我知道它应该消除一些可能导致读取部分写入信息的优化。我还听说这并不像使用锁定机制那样真正起作用。虽然我确实选择了这个解决方案,因为它为我减少了很多复杂性,而且看起来它的响应速度相当快(速度方面),但我确实对此感到不安。
是否有任何可能出现的问题或我应该从这种方法中意识到的问题?
回答
volatile可能不是正确的方法。volatile 的作用是强制从内存而不是缓存中读取值。读取或写入引用或小于 IntPtr 的值在 c# 中是原子的。但是如果没有某种内存屏障,该值可以被缓存,并且一个线程上的更改可能对其他线程不可见。Volatile 插入了一些内存屏障来解决一些可见性问题。
在这种情况下,您似乎没有替换字典,因此volatile什么也不做。但是,您提到您正在更新字典。这不是没有锁的线程安全。但是您可能会考虑使用 aConcurrentDictionary<TKey, TValue>代替。然而,并发字典只能保证字典本身是线程安全的,您仍然需要考虑程序的整体线程安全性。
此外,您主要关心的应该是程序是否正确,速度是次要的。
- @TobyB no. volatile is not a magic make thread safe keyword. It solves one particular, very narrow problem. And it is arguably better to use Interlocked.Exchange/Read even then. If in doubt you should use a *lock*. Locks have its own issues and dangers but it solves many of the possible concurrency problems. Writing multithreaded code is not the place to use trial and error, it is way to easy to write code fails 0.001% of the time and is impossible to debug. You need some understanding of the hazards.