0

很想知道是否有其他人看到过这个问题。我有一个锁定静态声明对象的应用程序,这样:

lock(Group.IsisGroups)
{
          do some stuff 
}

do-some-stuff 做了各种事情,我称之为尝试锁定同一个锁的例程之一。线程死锁。

我的猜测是,这个问题在某种程度上与我对反射的使用有关:在调用堆栈的中途,我通过在类定义中查找方法并调用 .Invoke() 来调用方法。结果的调用堆栈是这样的:

[In a sleep, wait, or join]  
[External Code]  
ConsoleApplication2.exe!Isis.Group.doLookup(Isis.Address gaddr) Line 3774 + 0x13 bytes  
ConsoleApplication2.exe!Isis.ReliableSender.GotIncoming(byte type, Isis.Address gaddr, Isis.Address sender, int minStable, Isis.Msg m) Line 10179 + 0x9 bytes  
ConsoleApplication2.exe!Isis.ReliableSender.doReceive.AnonymousMethod14(byte type, byte code, int seqn, int truePayLoadLen, int PreFragLen, Isis.Address sender, Isis.Address dest, Isis.Address gaddr, int minStable, int FID, int Fn, int nF, byte[] buf) Line 3120 + 0x80 bytes  
[External Code]  
ConsoleApplication2.exe!Isis.Msg.doInvokeSingle(System.Delegate del, byte[] barray, System.Type[] types) Line 11582 + 0x10 bytes  
ConsoleApplication2.exe!Isis.Msg.InvokeFromBArray(byte[] barray, System.Delegate del) Line 11527 + 0xf bytes  
ConsoleApplication2.exe!Isis.ReliableSender.doReceive(object os, Isis.Group g) Line 10034 + 0x71 bytes  
ConsoleApplication2.exe!Isis.ReliableSender.Receive(Isis.Group g) Line 10013 + 0xe bytes  
ConsoleApplication2.exe!Isis.ReliableSender.StartGroupReader.AnonymousMethod__6(object o) Line 9097 + 0xc bytes  
[External Code]  

因此,初始调用lock(Group.IsisGroups)是在堆栈的顶部方法中,ReliableSender.StartGroupReader当它在底部方法 doLookup 中调用 lock 时,代码会死锁。这些[External Code]块来自我调用反射Invoke()方法的地方,并且来自lock()导致事情死锁的调用。绝对是同一个对象被锁定,等等(当我的类被加载并且是类型时静态分配的对象,List<Isis.Group>当我添加和删除东西时,实际的 List 对象仍然存在。

关于可能导致这种情况的任何建议?

4

2 回答 2

1

我读对了吗?

因此,对 lock(Group.IsisGroups) 的初始调用是在堆栈的顶部方法中[...],并且当它在底部方法中调用 lock [...] 到 lock() 时代码会死锁,这会导致事情死锁.肯定是同一个对象被锁定。

您的方法的一些伪代码显示它们如何锁定会有所帮助,但根据我读到的内容,听起来您将同一个对象锁定在锁定中?

如果我没看错,这听起来像是发生了

lock(ob1)
{
  lock(ob1)
  {
  }
}

但你听起来很自信,所以我假设我误读了。

无论哪种方式,调用锁的方法的一些伪代码都会很好。:p

死锁是由多个方法/线程以“错误”的顺序锁定对象引起的。

于 2011-01-24T15:39:19.097 回答
0

好的,不想让这个打开,所以我的“答案”是这样的:首先,(抱歉)Bengie 和 Hans 似乎不明白,一个可重入锁出现故障。其次,我怀疑这是因为我使用了反射而发生的;不知何故,他们用来实现锁被同一个线程重新锁定的上下文信息显然受到了影响。

我将通过将代码更改为在初始调用期间不持有锁来解决此问题;基本上,我不会尝试重入获取这个锁。

应该警告遇到此线程的其他人:据我所知,我遇到的只能是 .NET 错误。而且也不是很难激怒。

于 2011-01-26T02:37:57.623 回答