2011-04-04 68 views
7

我有一个使用读写锁的类。多线程锁测试

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

编辑:
一些澄清:

这是从C++/CLI代码衍生的C#代码,具有锁在C++级......没那么简单。这就是为什么我正在寻找一个测试设计,而不是设计如何锁定它。

有需要被检查,同时多线程的几件事情:

无死锁(最明显的)
正确性(如果我在1个线程更新它,它会在其他看出)
原子写(如果我在一个线程中写的,我将能够读取只有当满值写入)
公平(可能是更多的理论来证明,如果我使用互斥反正应该是真实的)

+8

是否将“小心”算作设计模式? – 2011-04-04 08:17:53

+2

恐怕“谨慎”不会涵盖所有糟糕的情况 – 2011-04-04 08:18:45

+0

-1,因为本周最糟糕的设计模式。 – sehe 2011-04-04 08:27:05

回答

6

您可能需要阅读使用SyncLock和SyncRoot来创建关于如何l的通用模式ock你的对象。既然你不想锁定一个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(); 
} 

一个bad pattern是做lock(this)NEVER做到这一点!

还有一些叫做Double-checked locking的东西,它不是特定于.NET的,您可能还想阅读"Strategized Locking, Thread-safe Interface, and Scoped Locking"上的这篇论文。

测试线程安全

如果你想测试线程安全的,我建议你看看"Unit test for thread safety",公认的答案指向Microsoft Chess它可以帮助您确定您的应用程序死锁。

+0

这是一个从C++ /在C++级别锁定的CLI代码...并不那么简单。这就是为什么我正在寻找一个测试设计,而不是设计如何锁定它。 – 2011-04-04 08:30:55

+0

@Yochai,所以你想强调你的应用程序陷入僵局?那么你在寻找的是如何验证你的应用程序不会陷入僵局的测试策略?那是对的吗? – 2011-04-04 08:32:21

+0

多线程测试...线程不会死锁。公平。值得到正确读取,而不是在写入中。还有更多的多线程比死锁 – 2011-04-04 08:36:30

2

你知道这个问题,那是第一步。它(通常)是NP-complete ...然而,有一些工具:

  • helgrind的Valgrind的工具包的

一部分;这将能够验证最常用的同步原语的使用;你可能能够告诉它关于你自己的基元。

  • 英特尔Parallel Inspector中

同样让你在使用过程中形容自己的图元进行验证。见Intel Inspector reports a data race in my spinlock implementation

更新我刚刚发现GNU的libstdc(++)和GNU GCC极大地改善了他们的支持Helgrind的,指的是4.6.X的发行说明和this page

网站还链接了以下附加工具

+0

Sry有点错过了C#标签。这里应该没有真正的区别,但这会使应用这些工具变得更加困难 – sehe 2011-04-04 08:33:42