【问题标题】:C# Thread and lockC#线程和锁
【发布时间】:2017-10-18 09:49:12
【问题描述】:

我测试简单的代码

    static Thread _readThread = null;
    static private Object thisLock = new Object();
    static int a = 1;

    private static void ReadComPort()
    {
        lock (thisLock)
        {
            for (int i = 0; i < 3; i++)
            {
                Console.WriteLine(Thread.CurrentThread.Name + "  " + a++.ToString());
                Thread.Sleep(1000);
            }
        }
    }

    static void Main(string[] args)
    {
        for (int i = 0; i < 3; i++)
        {
            _readThread = new Thread(new ThreadStart(ReadComPort));
            _readThread.IsBackground = true;
            _readThread.Name = i.ToString();
            _readThread.Start();
            //Thread.Sleep(50);
        }

        Console.WriteLine("End");
        Console.ReadKey();
    }

但是为什么执行顺序和线程启动是混乱的: 0,2,1 为什么?

控制台输出:

0  1
End
0  2
0  3
2  4
2  5
2  6
1  7
1  8
1  9

【问题讨论】:

  • 期待为什么?请注意,您的低迭代次数意味着 线程之间的任何交互都不太可能发生。
  • 当一个线程启动时,它不保证立即运行,也不保证与其他线程相比按启动顺序运行
  • 你可以使用Task.ContinueWith,队列来运行线程,队列/优先级来同步对控制台的访问,还有什么......应该更多,但绝对不要运行一些线程并期望它们将自己组织为你没有告诉他们...
  • 好吧,你不希望超过 1 个线程拉你的 ComPort。

标签: c# multithreading locking


【解决方案1】:

因为您不能期望线程以特定顺序启动或运行。操作系统以它想要的方式调度线程。有时它会暂停一个线程,执行另一个线程,然后再返回原来的线程。

在这里您可以看到线程几乎同时启动。显然(从输出)线程 0 赢得了第一个锁。然后,纯属偶然,线程 2 比线程 1 更早获得锁。这可能完全不同,因为线程是在彼此之后不久创建的。如前所述:没有保证。

【讨论】:

    【解决方案2】:

    锁不保证顺序:Does lock() guarantee acquired in order requested?

    另外,在你的代码中,你应该等待你的线程在你的 for 循环结束时完成,以便在开头没有“结束” - 如果你按下一个键,你将在你的线程仍在运行时退出,你可能会有意想不到的行为。

    【讨论】:

      【解决方案3】:

      仔细阅读 C# 参考资料。

      https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement

      在那里,你找不到任何关于线程进入锁块的顺序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-30
        • 1970-01-01
        • 1970-01-01
        • 2016-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多