由于在C#的障碍类中删除了参与者而导致的奇怪死锁

时间:2013-02-03 15:48:16

标签: c# barrier

当使用C Sharp的屏障时,我想出了一个非常奇怪的僵局。目的是了解RemoveParticipants()实际上是如何运作的。我从2个线程(2个动作)开始,每个执行barrier.SignalAndWait();。之后,一个线程将删除一个参与者。从那时起,屏障计数仅为1.通过右边,所有剩余的barrier.SignalAndWait();应该没有任何死锁。但是,以下程序陷入僵局。

using System;
using System.Threading;
using System.Threading.Tasks;

class BarrierDemo
{
    /* Print out barrier's phase and count */
    static void printInfo(int action, Barrier b){
        Console.WriteLine("action {0} : phase = {1} ; count = {2} ",action, b.CurrentPhaseNumber, b.ParticipantCount);
    }

    static void Main(string[] args)
    {
        Barrier barrier = new Barrier(2);

        Action action1 = () =>
        {
            printInfo(1,barrier);

            barrier.SignalAndWait();

            //Thread.Sleep(1000);

            printInfo(1,barrier);

            barrier.SignalAndWait();

            printInfo(1,barrier);

            Console.WriteLine("action 1: terminating");
        };

        Action action2 = () =>
        {
            printInfo(2,barrier);

            barrier.SignalAndWait();

            Thread.Sleep(1000);
            Console.WriteLine("action 2 : wake up 1 ");
            barrier.RemoveParticipants(1);
            Thread.Sleep(1000);
            Console.WriteLine("action 2 : wake up 2 ");
            printInfo(2,barrier);

            barrier.SignalAndWait(); // **DEADLOCK HERE**

            printInfo(2,barrier);
        };

        /* Execute 2 actions in parallel */
        Parallel.Invoke(action1,action2);

        Console.WriteLine("Going to dispose");
        barrier.Dispose();

    }

}

跟踪时收到的输出是:

action 1 : phase = 0 ; count = 2
action 2 : phase = 0 ; count = 2
action 1 : phase = 1 ; count = 2
action 2 : wake up 1
action 1 : phase = 2 ; count = 1
action 1: terminating
action 2 : wake up 2
action 2 : phase = 2 ; count = 1
[Deadlock]

另一个注意事项是,如果我在action2中表示所有System.Sleep()并在action1中解除对System.Sleep()的反应。然后程序终止:

action 1 : phase = 0 ; count = 2
action 2 : phase = 0 ; count = 2
action 2 : wake up 1
action 2 : wake up 2
action 2 : phase = 1 ; count = 1
action 2 : phase = 2 ; count = 1
action 1 : phase = 2 ; count = 1
action 1 : phase = 3 ; count = 1
action 1: terminating
Going to dispose

我不确定为什么上面的程序会死锁?为什么action2barrier.SignalAndWait();停止时会停止(屏障数只有1)?

感谢您查看和提供任何帮助。

  

解决方案摘要:

     

此问题与平台有关。由于在非本地平台上运行它,我遇到了死锁。我尝试使用2个在线编译器(1)http://www.compileonline.com/compile_csharp_online.php,(2)https://compilr.com/并解决了僵局。第一个唯一的编译器使用mono执行Windows可执行文件(非本机)。我不确定第二个在线编译器的平台。

     

但是,正如Phillip Scott Givenssvick所建议的那样,我在运行.Net 4.0的Visual C#2010上本机安装并运行了示例,并且死锁消失了。

0 个答案:

没有答案