我有一个使用读写锁的类。
我想知道我是否正确锁定并保护了所有方法 是否有测试设计模式来检查锁是否设置正确?
修改
一些澄清:
这是一个源自C ++ / CLI代码的C#代码,它具有C ++级别的锁...不那么简单。这就是我正在寻找测试设计的原因,而不是设计如何锁定它。
多线程时需要检查一些事项:
没有死锁(最明显的)
正确性(如果我在1个线程中更新它将在另一个线程中看到)
原子写入(如果我在一个线程中写入,只有在写入完整值时才能读取)
公平性(如果我还是使用Mutex,可能会更加理论化,
答案 0 :(得分:6)
您可能希望阅读SyncLock和SyncRoot,它们用于创建有关如何锁定对象的常见模式。由于您不想锁定enitre对象,因此您经常拥有一个锁定的SyncRoot。
这方面的一个例子是ArrayList或ICollection,它们都有一个用于锁定集合的SyncRoot。您可以阅读有关Thread Synchronization on MSDN的更多信息。
但通常它就像Marc指出的那样,小心,测试,测试,测试并做更多测试!
SyncLock示例
public class Person
{
public decimal Salary { get;set; }
public string Name { get; set; }
public readonly object SyncRoot = new object();
}
然后您可以像这样进行锁定:
var person = new Person { Name = "Bill", Salary = 1000000 };
lock(person.SyncRoot)
{
IncreasSalary();
}
lock(this)
要做{{1}} 从不这样做!
还有一些名为bad pattern的东西,它不是特定于.NET的,您可能还想在Double-checked locking上阅读本文。
测试线程安全性
如果您想测试线程安全性,我建议您查看"Strategized Locking, Thread-safe Interface, and Scoped Locking","Unit test for thread safety"接受的答案点,它可以帮助您识别应用程序中的死锁。
答案 1 :(得分:2)
你知道问题,这是第一步。它(通常)是NP完全的...但是有工具:
valgrind工具包的一部分;这将能够验证最常见的同步原语的使用;你或许可以告诉它你自己的原语。
同样地,让我们在使用过程中描述您自己的原语以进行验证。见Intel Inspector reports a data race in my spinlock implementation
更新我刚刚发现GNU libstdc(++)和GNU gcc已大大改进了对Helgrind的支持,请参阅4.6.x发行说明和this page
它还链接了以下附加工具