ChristianMurschall
ChristianMurschall

Reputation: 1711

Why does a locked Parallel foreach not deadlock right away?

I noticed a deadlock in my program an relatively quickly found the reason. I was calling a locked getter from a Parallel.Foreach loop. Generally nested locks are no problem, a syncronous for loop does indeed not deadlock. But why does the Parallel.Foreach loop deadlock and why does it execute more often than two times?

I put an example below.

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);
        }
    }
}

The output varies from run to run. But often it is like hello 0 hello 4 hello 5 hello 8 hello 9

Upvotes: 1

Views: 693

Answers (1)

Enigmativity
Enigmativity

Reputation: 117175

The lock (lockObject) in RunTest means that only the current thread can pass through any and all subsequent lock (lockObject) until the code Parallel.For(0, 10, sayHello) completes.

Since you get some output from sayHello this means that Parallel.For is using the current thread for some of its computation - remember it partitions the number of calls it hands on to each thread based on the cores available on your CPU - and those are hitting the Console.WriteLine calls. But the other threads it is using cannot enter the lock until the Parallel.For completes.

That's why some of the calls succeed.

Upvotes: 4

Related Questions