为什么锁定的 Parallel foreach 不会立即死锁?
Why does a locked Parallel foreach not deadlock right away?
我注意到我的程序出现了死锁,并且很快就找到了原因。我正在从 Parallel.Foreach
循环中调用锁定的 getter。
一般嵌套锁没问题,一个syncronous for
loop确实不会死锁。但是为什么 Parallel.Foreach
循环会死锁,为什么执行次数超过两次?
下面我举个例子
public class Program
{
public static void Main(string[] args)
{
new Test().RunTest();
Console.WriteLine("Test finished");
}
}
class Test
{
object lockObject = new object();
public void RunTest()
{
lock (lockObject)
{
Parallel.For(0, 10, sayHello);
}
}
void sayHello(int i)
{
lock (lockObject)
{
Console.WriteLine("hello " + i);
}
}
}
输出与 运行 运行 不同。但很多时候就像
hello 0
hello 4
hello 5
hello 8
hello 9
RunTest
中的lock (lockObject)
表示只有当前线程可以通过任何和所有后续lock (lockObject)
,直到代码Parallel.For(0, 10, sayHello)
完成。
由于您从 sayHello
获得了一些输出,这意味着 Parallel.For
正在使用当前线程进行某些计算 - 请记住,它根据您的 CPU 上可用的内核 - 那些正在调用 Console.WriteLine
的内核。但是它正在使用的其他线程在 Parallel.For
完成之前无法进入 lock
。
这就是一些调用成功的原因。
我注意到我的程序出现了死锁,并且很快就找到了原因。我正在从 Parallel.Foreach
循环中调用锁定的 getter。
一般嵌套锁没问题,一个syncronous for
loop确实不会死锁。但是为什么 Parallel.Foreach
循环会死锁,为什么执行次数超过两次?
下面我举个例子
public class Program
{
public static void Main(string[] args)
{
new Test().RunTest();
Console.WriteLine("Test finished");
}
}
class Test
{
object lockObject = new object();
public void RunTest()
{
lock (lockObject)
{
Parallel.For(0, 10, sayHello);
}
}
void sayHello(int i)
{
lock (lockObject)
{
Console.WriteLine("hello " + i);
}
}
}
输出与 运行 运行 不同。但很多时候就像
hello 0
hello 4
hello 5
hello 8
hello 9
RunTest
中的lock (lockObject)
表示只有当前线程可以通过任何和所有后续lock (lockObject)
,直到代码Parallel.For(0, 10, sayHello)
完成。
由于您从 sayHello
获得了一些输出,这意味着 Parallel.For
正在使用当前线程进行某些计算 - 请记住,它根据您的 CPU 上可用的内核 - 那些正在调用 Console.WriteLine
的内核。但是它正在使用的其他线程在 Parallel.For
完成之前无法进入 lock
。
这就是一些调用成功的原因。