多线程锁测试

时间:2011-04-04 08:16:08

标签: c# multithreading design-patterns locking

我有一个使用读写锁的类。

我想知道我是否正确锁定并保护了所有方法 是否有测试设计模式来检查锁是否设置正确?

修改
一些澄清:

这是一个源自C ++ / CLI代码的C#代码,它具有C ++级别的锁...不那么简单。这就是我正在寻找测试设计的原因,而不是设计如何锁定它。

多线程时需要检查一些事项:

没有死锁(最明显的)
正确性(如果我在1个线程中更新它将在另一个线程中看到)
原子写入(如果我在一个线程中写入,只有在写入完整值时才能读取)
公平性(如果我还是使用Mutex,可能会更加理论化,

2 个答案:

答案 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完全的...但是有工具:

  • helgrind
  

valgrind工具包的一部分;这将能够验证最常见的同步原语的使用;你或许可以告诉它你自己的原语。

  • 英特尔Parallel Inspector

同样地,让我们在使用过程中描述您自己的原语以进行验证。见Intel Inspector reports a data race in my spinlock implementation

更新我刚刚发现GNU libstdc(++)和GNU gcc已大大改进了对Helgrind的支持,请参阅4.6.x发行说明和this page

它还链接了以下附加工具