Не могли бы вы объяснить, почему этот код взаимоблокируется?
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» ждет вечно. Теперь понятно, спасибо!
testLock
. Каждый другой поток (отличный от потока 1!), созданныйParallel.ForEach
, также хочет заблокироватьtestLock
, но он все еще заблокирован потоком 1. Thread1 ожидает завершения всехParallel
-потоков = взаимоблокировка. - person   schedule 15.09.2014Parallel
решил запустить все итерации в текущем основном потоке (тот, который вызываетParallel.ForEach
). Насколько я знаю, он может сделать это, если у вас есть только одно ядро... во всех остальных случаях: да, он заблокируется... потому что вы записали тупик. - person Marc Gravell   schedule 15.09.2014