如何在C#中使用多个变量来锁定范围

时间:2010-05-20 13:17:04

标签: c# multithreading locking critical-section

我的情况是,只有当两个更衣室对象空闲时才应执行代码块。

我希望有类似的东西:

lock(a,b)
{
    // this scope is in critical region
} 

然而,似乎没有那样的东西。这是否意味着这样做的唯一方法是:

lock(a)
{
    lock(b)
    {
        // this scope is in critical region
    }
}

这甚至可以按预期工作吗?虽然代码编译,但我不确定它是否会实现我所期望的。

3 个答案:

答案 0 :(得分:16)

lock(a) lock(b) { // this scope is in critical region }

这可能会阻塞,直到线程可以获取a的锁定。然后,通过获取该锁,它将阻塞,直到线程可以获取b的锁。所以这可以按预期工作。

但是,你必须小心不要在其他地方这样做:

lock(b) lock(a) { // this scope is in critical region }

这可能会导致死锁情况,其中线程1已获取a的锁定并正在等待获取b的锁定,并且线程2已获取{{1}的锁定并且正在等待获取b的锁定。

答案 1 :(得分:11)

请求两者的锁定应该可以正常工作。 lock(a)将被阻止,直到a空闲为止。锁定后,lock(b)会阻止,直到您拥有b。之后,你们两个都有。

在这里你需要非常小心的一件事是订单。如果您要执行此操作,请确保始终锁定a,然后锁定b。否则你很容易发现自己陷入僵局。

答案 2 :(得分:5)

我期待它,尽管有可能导致死锁的情况。

通常,代码将尝试锁定a,然后如果成功则继续锁定b。这意味着只有在可以锁定ab的情况下,它才会执行代码。这就是你想要的。

但是,如果某些其他代码已经锁定b,则此代码将无法执行您所期望的操作。您还需要确保在需要锁定ab的任何位置时,您尝试以相同的顺序获取锁定。如果先获得b然后再获得a,则会导致死锁。