C#中的重入锁 [英] Re-entrant locks in C#

查看:62
本文介绍了C#中的重入锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 .NET 上使用 C# 以下代码会导致死锁吗?

Will the following code result in a deadlock using C# on .NET?

 class MyClass
 {
    private object lockObj = new object();

    public void Foo()
    {
        lock(lockObj)
        { 
             Bar();
        }
    }

    public void Bar()
    {
        lock(lockObj)
        { 
          // Do something 
        }
    }       
 }

推荐答案

不需要,只要您锁定同一个对象即可.递归代码有效已经锁定,因此可以不受阻碍地继续.

No, not as long as you are locking on the same object. The recursive code effectively already has the lock and so can continue unhindered.

lock(object) {...} 是使用 监控 类.正如 Marc 指出的Monitor 允许重入,因此反复尝试锁定一个当前线程已经拥有锁的对象可以正常工作.

lock(object) {...} is shorthand for using the Monitor class. As Marc points out, Monitor allows re-entrancy, so repeated attempts to lock on an object on which the current thread already has a lock will work just fine.

如果您开始锁定不同 对象,那您就必须小心了.特别注意:

If you start locking on different objects, that's when you have to be careful. Pay particular attention to:

  • 始终以相同的顺序获取给定数量的对象的锁.
  • 始终以与获取锁的相反顺序释放锁.
  • Always acquire locks on a given number of objects in the same sequence.
  • Always release locks in the reverse sequence to how you acquire them.

如果您违反这些规则中的任何一条,您几乎肯定会在某些时候遇到死锁问题.

If you break either of these rules you're pretty much guaranteed to get deadlock issues at some point.

这是一个很好的网页,描述了 .NET 中的线程同步:http://dotnetdebug.ne​​t/2005/07/20/monitor-class-avoiding-deadlocks/

Here is one good webpage describing thread synchronisation in .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/

此外,一次锁定尽可能少的对象.考虑在可能的情况下应用粗粒度锁.这个想法是,如果您可以编写代码,以便有一个对象图,并且您可以在该对象图的根上获取锁,那么就这样做.这意味着您对该根对象拥有一个锁,因此不必太担心获取/释放锁的顺序.

Also, lock on as few objects at a time as possible. Consider applying coarse-grained locks where possible. The idea being that if you can write your code such that there is an object graph and you can acquire locks on the root of that object graph, then do so. This means you have one lock on that root object and therefore don't have to worry so much about the sequence in which you acquire/release locks.

(进一步说明,您的示例在技术上不是递归的.要使其成为递归,Bar() 必须调用自身,通常作为迭代的一部分.)

(One further note, your example isn't technically recursive. For it to be recursive, Bar() would have to call itself, typically as part of an iteration.)

这篇关于C#中的重入锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆