C#尝试重新锁定某个死锁的、明显的错误
我很想知道是否有其他人见过这个问题。我有一个锁定静态声明对象的应用程序,如下所示:C#尝试重新锁定某个死锁的、明显的错误,c#,locking,deadlock,reentrancy,C#,Locking,Deadlock,Reentrancy,我很想知道是否有其他人见过这个问题。我有一个锁定静态声明对象的应用程序,如下所示: lock(Group.IsisGroups) { do some stuff } Dosomestuff做各种各样的事情,我称之为的一个例程尝试锁定同一个锁。线程死锁 我猜想这个问题与我对反射的使用有关:在调用堆栈的中间,我通过在类定义中查找方法并调用.Invoke()来调用方法。产生以下结果的调用堆栈: [In a sleep, wait, or join] [External Co
lock(Group.IsisGroups)
{
do some stuff
}
Dosomestuff做各种各样的事情,我称之为的一个例程尝试锁定同一个锁。线程死锁
我猜想这个问题与我对反射的使用有关:在调用堆栈的中间,我通过在类定义中查找方法并调用.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)
的初始调用位于堆栈reliablessender.StartGroupReader
的顶部方法中,当调用底部方法doLookup中的lock时,代码会死锁。[External code]
块来自我调用reflectionInvoke()
方法的地方,以及调用导致死锁的lock()。肯定是同一个对象被锁定,等等(当我的类被加载时,对象是静态分配的,并且类型是List
,当我添加和删除东西时,实际的List对象仍然保持完整
有什么建议可以导致这种情况吗?我读对了吗
因此,对lock(Group.IsisGroups)的初始调用在堆栈[…]的顶部方法中,当它将底部方法[…]中的lock调用到lock()中时,代码会死锁,从而导致死锁。肯定是同一个对象被锁定
您的方法的一些伪代码显示了它们是如何锁定的,这会有所帮助,但是根据我读到的内容,听起来好像您在锁中锁定了同一个对象
如果我读对了,这听起来像是发生了
lock(ob1)
{
lock(ob1)
{
}
}
但是你听起来很自信,所以我想我看错了
无论哪种方式,调用锁的方法的一些伪代码都很好。:p
死锁是由多个方法/线程以“错误”的顺序锁定对象造成的。好的,我不想让它打开,所以我的“答案”是:首先,(对不起)Bengie和Hans似乎不太明白,可重入的锁发生了故障。其次,我怀疑这是因为我使用了反射;不知何故,他们用来意识到锁被同一线程重新锁定的上下文信息显然受到了影响
我将通过更改代码以在初始调用期间不持有锁来修复此问题;基本上,我不会尝试以可重入方式获取此锁
其他遇到此线程的人应该得到警告:据我所知,我遇到的只是一个.NET错误。这也不是很难引起。PS:并不是每次都会发生。事实上,只有当我在双处理器上同时启动几个应用程序副本,从而使.NET承受相当大的负载时,才会发生这种情况奔腾。所有这些都是最新的版本。所以我在想某种.NET错误?在99%的情况下,当人们认为它是一个.NET错误时,结果证明它只是一些意料之外的代码行为。在这种情况下,我不确定什么是错误的,但我倾向于不相信它是一个.NET错误,因此不是你的错误错误。看看其他线程,其中一个线程获得了锁定对象,并被其他线程卡住了。克里斯,我在教一门课。无论如何,我不能勾选“向上”箭头,因为你们没有给我足够的分数或其他东西。汉斯,如果顶级过程在锁(x)内块,其他线程如何获得(x)上的锁?实际上,我的代码有一个锁定(x){lock(x);}的线程至少根据VS 2010调试器,内部锁是阻塞的。这让我感到困惑。如果线程在堆栈顶部锁定了x,它怎么能等待锁定x 5或6调用堆栈?同一个线程。我通常不会以这种方式编写代码,所以我忘了。无论如何,必须至少有两个对象被锁定才能执行此操作死锁即将发生。另一个对象是什么?还有什么其他方法和线程称之为锁?Bengie,我的代码是100K行C#,所以我怀疑你是否真的想要它。Hans,就是这样。这正是我所说的:reetrant锁请求正在挂起。Bengie,我教这方面的课程,还写了一本教科书。我确实知道死锁的原因。通常情况下,可重入锁定方法不应挂起。因此,某种原因导致.NET系统变得混乱,无法识别这是一个可重入请求。这就是我的问题:有人知道他们是如何实现此功能的,特别是如何“愚弄”它吗?因为显然我正在这么做。