您能否解释一下此代码为什么会死锁?

int[] testlist = new int[ ] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
lock ( testlock ) {
    Parallel.ForEach( testlist, new ParallelOptions( ) { MaxDegreeOfParallelism = 90 }, ( int i ) => {
        Console.WriteLine( "hi there before " + i + " " + Monitor.IsEntered( testlock ) );
        lock ( testlock ) {
            Console.WriteLine( "hi there inner " + i + " " + Monitor.IsEntered( testlock ) );
        }
        Console.WriteLine( "hi there after " + i + " " + Monitor.IsEntered( testlock ) );
    } );
}


当然,如果没有周围的锁,此代码也不会死锁。

编辑:

感谢您的解释。典型输出为:

hi there before 3 True
hi there inner 3 True
hi there after 3 True
hi there before 4 True
hi there inner 4 True
hi there after 4 True
hi there before 5 True
hi there inner 5 True
hi there after 5 True
hi there before 6 True
hi there inner 6 True
hi there after 6 True
hi there before 7 True
hi there inner 7 True
hi there after 7 True
hi there before 8 True
hi there inner 8 True
hi there after 8 True
hi there before 9 True
hi there inner 9 True
hi there after 9 True
hi there before 10 True
hi there inner 10 True
hi there after 10 True


实际上,典型的执行涉及我计算机上的两个线程:一个阻塞等待锁定(“ 1”阻塞),另一个正在运行其他迭代(从3到10,请注意输出的线性)。 “ 1”线程永远等待。现在很清楚,谢谢!

最佳答案

这是行不通的,因为您肯定在这里创建了死锁:

外部lock(testlock)锁定testlock,然后Parallel.ForEach开始在多个线程中处理您的testlist。现在这些线程到达内部lock(testlock),但是由于它仍被外部线程锁定在其线程中,因此无法再次锁定它。>外部lock直到处理完成后才释放。直到外部lock释放->死锁才完成

您可以使用MaxDegreeOfParallelism = 1轻松验证这一点:然后所有内容都在主线程中运行,并且级联锁不会死锁,因为它可以再次锁定,因为它是同一线程。

您正在尝试做什么-如果您能解释一下,我们可以为您提供帮助吗?

注意:
如果您的系统没有90! CPU的使用MaxDegreeOfParallelism = 90对性能没有帮助-建议将该数字保持小于或等于您的CPU /核心数(您可以通过Environment.ProcessorCount来获得)。

关于c# - 在Parallel.ForEach周围和内部均具有锁的死锁,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25846732/

10-16 05:13