blu*_*lds 18 c# multithreading
假设你有一个内存中的字符串列表,以及一个多线程系统,有许多读者但只有一个编写器线程.
一般来说,是否可以在C#中实现这种系统而不使用锁?实现是否会对线程如何交互做出任何假设(或者限制它们可以做什么,何时做)?
Bri*_*eon 25
是.诀窍是确保列表保持不变.编写器将对主集合进行快照,修改快照,然后将快照发布到包含对主集合的引用的变量.以下示例演示了这一点.
public class Example
{
// This is the immutable master collection.
volatile List<string> collection = new List<string>();
void Writer()
{
var copy = new List<string>(collection); // Snapshot the collection.
copy.Add("hello world"); // Modify the snapshot.
collection = copy; // Publish the snapshot.
}
void Reader()
{
List<string> local = collection; // Acquire a local reference for safe reading.
if (local.Count > 0)
{
DoSomething(local[0]);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法有几点需要注意.
volatile使用,为什么在读者端获取本地参考,等等.如果您不理解这些原因,请不要使用该模式.有太多可能出错的地方.由于上述限制,这将使您受益的情况非常有限.最大的问题是写入首先要求完整拷贝,因此它们可能很慢.但是,如果写入很少,那么这可能是可以忍受的.
我在这里的答案中描述了更多的模式,包括一个对多个作者都安全的模式.
对于线程库来说,这是一个相当常见的请求 - 这种锁通常被称为"读写器锁",或者是该主题的一些变体.我没有必要专门使用C#实现,但有一个:http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx
当然,你遇到的问题是,如果读者总是在阅读,你将永远无法让作家写作.我相信你必须自己处理.
(好吧,所以它在技术上仍然是一个"锁定",但它不是C#"锁定"构造,它是一个专门为问题中所述目的而设计的更复杂的对象.所以我猜它是否是一个正确的答案在某种程度上取决于语义和他为什么问这个问题.)
您还可以使用Microsoft的新Immutable Collections库:http://blogs.msdn.com/b/bclteam/archive/2012/12/18/preview-of-immutable-collections-released-on-nuget.aspx
注意:这与Concurrent Collections完全分开.