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

Sha*_*fiz 9 c# multithreading locking critical-section

我有一种情况,即只有两个更衣室对象空闲时才应执行代码块.

我希望有类似的东西:

lock(a,b)
{
    // this scope is in critical region
} 
Run Code Online (Sandbox Code Playgroud)

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

lock(a)
{
    lock(b)
    {
        // this scope is in critical region
    }
}
Run Code Online (Sandbox Code Playgroud)

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

dtb*_*dtb 16

lock(a) lock(b) { // this scope is in critical region }
Run Code Online (Sandbox Code Playgroud)

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

但是,您必须小心不要在其他地方执行此操作:

lock(b) lock(a) { // this scope is in critical region }
Run Code Online (Sandbox Code Playgroud)

这可能导致死锁情况,其中线程1已获取锁a并且正在等待获取锁b,并且线程2已获取锁b并且正在等待获取锁a.


Her*_*rms 11

在两者上请求锁定应该可以正常工作. lock(a)将阻止直到a免费.一旦你拥有了这个锁,lock(b)你就会阻止它b.之后,你们两个都有.

在这里你需要非常小心的一件事是订单.如果您要这样做,请确保在锁定之前始终a锁定b.否则你很容易发现自己陷入僵局.


Chr*_*isF 5

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

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

但是,如果某些其他代码已经锁定,b则此代码将无法执行您所期望的操作.您还需要确保无论何时需要锁定两者,ab尝试以相同的顺序获取锁定.如果b先获得,那么a就会导致死锁.