很想知道是否有其他人见过这个问题。我有一个应用程序,以这种方式锁定静态声明的对象:
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中调用锁时代码死锁。 [External Code]
块来自我称之为反射Invoke()
方法的位置,以及从调用lock()
中导致事件陷入僵局的方法。肯定是同一个被锁定的对象等(当我的类被加载并且类型为List<Isis.Group>
时,该对象被静态分配,而当我添加和删除东西时,实际的List对象仍然存在。
有关可能导致此问题的任何建议吗?
答案 0 :(得分:1)
我是否正确阅读了这个?
所以对lock(Group.IsisGroups)的初始调用是在堆栈顶部方法[...]和代码死锁时它在底部方法[...]中调用lock导致lock()导致死锁的事情。无限期被锁定的对象。
你的方法的一些伪代码显示了它们如何锁定会有所帮助,但根据我读到的内容,听起来就像你用锁来锁定同一个对象?
如果我正确地读了这个,听起来好像发生了这个
lock(ob1)
{
lock(ob1)
{
}
}
但你听起来很自信,所以我假设我读错了。
无论哪种方式,调用锁的方法的一些伪代码都会很好。 :P
死锁是由多个方法/线程以“错误”顺序锁定对象引起的。
答案 1 :(得分:0)
好吧,不要让这个开放,所以我的“回答”是这样的:首先,(对不起)Bengie和Hans似乎并不理解,确实有一个折返式锁定发生故障。其次,我怀疑这种情况正在发生,因为我使用了反射;不知何故,他们用来意识到锁被同一个线程重新锁定的上下文信息显然受到了影响。
我打算通过将我的代码更改为在初始调用期间不保持锁定来解决此问题。基本上,我不会试图重新获得这个锁。
应该警告其他遇到此线程的人:据我所知,我遇到的只是.NET漏洞。而且也不是很难激起。