【问题标题】:Why is this thread example not predictable at all (outputs different result each time)?为什么这个线程示例根本不可预测(每次输出不同的结果)?
【发布时间】:2018-08-19 09:44:11
【问题描述】:

我正在尝试了解线程。所以我在一本官方书籍中看到了这篇文章:

public static class Program
{
    public static void ThreadMethod()
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Thread Step: {0}", i); // A - see comment!!
            Thread.Sleep(0); // B 
        }
    }
    public static void Main()
    {
        Thread t = new Thread(new ThreadStart(ThreadMethod));
        t.Start();
        for (int i = 0; i < 4; i++)
        {
            Console.WriteLine("This is supposedly the main thread.");
            Thread.Sleep(0);
        }
        t.Join();

        Console.ReadLine();
    }
}

现在,书中说预期的行为应该是这样的(暗示输出是可预测的,因为如果您知道规则以及如何配置线程,线程是可预测的):

// Displays
//This is supposedly the main thread.
//Thread step: 0
//This is supposedly the main thread.
//Thread step: 1
//This is supposedly the main thread.
//Thread step: 2
//This is supposedly the main thread.
//Thread step: 3
//Thread step: 4
//Thread step: 5
//Thread step: 6
//Thread step: 7
//Thread step: 8
//Thread step: 9
//Thread step: 10

但是,每次运行控制台应用程序的实际结果都不同,为什么? 其次,我希望首先在屏幕上看到“Thread Step:0”,因为 A)第一个线程将其输出到控制台,并且仅在此之后 B)运行 Thread.Sleep(0),这意味着当前线程被放置休眠以等待另一个同等优先级的线程来接管(如果可用)。

This is supposedly the main thread.
This is supposedly the main thread.
Thread Step: 0
This is supposedly the main thread.
Thread Step: 1
This is supposedly the main thread.
Thread Step: 2
Thread Step: 3
Thread Step: 4
Thread Step: 5
Thread Step: 6
Thread Step: 7
Thread Step: 8
Thread Step: 9

再次运行,得到另一个结果:

This is supposedly the main thread.
This is supposedly the main thread.
Thread Step: 0
Thread Step: 1
Thread Step: 2
Thread Step: 3
Thread Step: 4
Thread Step: 5
Thread Step: 6
Thread Step: 7
Thread Step: 8
Thread Step: 9
This is supposedly the main thread.
This is supposedly the main thread.

还有一个:

This is supposedly the main thread.
Thread step: 0
This is supposedly the main thread.
Thread step: 1
Thread step: 2
Thread step: 3
Thread step: 4
Thread step: 5
Thread step: 6
Thread step: 7
Thread step: 8
Thread step: 9
This is supposedly the main thread.
This is supposedly the main thread.

还有一个:

This is supposedly the main thread.
Thread step: 0
This is supposedly the main thread.
Thread step: 1
This is supposedly the main thread.
Thread step: 2
This is supposedly the main thread.
Thread step: 3
Thread step: 4
Thread step: 5
Thread step: 6
Thread step: 7
Thread step: 8
Thread step: 9

还有一个:

Thread step: 0
Thread step: 1
This is supposedly the main thread.
Thread step: 2
This is supposedly the main thread.
This is supposedly the main thread.
This is supposedly the main thread.
Thread step: 3
Thread step: 4
Thread step: 5
Thread step: 6
Thread step: 7
Thread step: 8
Thread step: 9

【问题讨论】:

  • bolov,你在书中的摘录/代码片段中看到了很多次,在摘录的下面是输出。没有免责声明,在这种情况下,输出实际上是可能的输出之一。它之前提到可以对线程进行优先级排序,但未能将这个想法与他们给出的示例联系起来。

标签: c# multithreading thread-sleep


【解决方案1】:

这是因为你的程序中有2个线程,一个是主线程,正在执行main方法,另一个是在这个main方法内部创建的线程,正在执行ThreadMethod方法。这两个线程正在访问一个公共输出,在这种情况下是您的控制台,并且操作系统可以选择以任何顺序安排它们的访问。这就是为什么如果你多次运行这个程序,每次你都会得到不同的顺序。日程安排不在您的程序的控制范围内。

【讨论】:

    【解决方案2】:

    我认为要学习线程,您需要了解进程、CPU 在计算机中的工作方式。他们如何分配/安排任务。

    线程永远无法预测,不确定这本书在什么意义上说,但是 CPU 正在调度这些任务,并且永远不知道哪个先开始。您可以分配优先级、监控令牌等技术来控制多线程中的某些行为。

    您在控制台上看到的内容可能令人困惑,但是,这样看,线程异步运行,这意味着如果两个进程同时执行Console.WriteLine,cpu 仍然需要决定首先显示哪个输出关于 CPU 的调度方式。

    【讨论】:

    • 在书中有他们输出结果的代码,但没有免责声明这是一个可能的输出,并且不是每次都呈现相同的。所以误导了我。非常感谢 Luminous。
    • 所以我理解你所说的优先级,但是一旦 CPU 决定哪个是优先级,为什么它会在 Thread.Sleep(0); 之后“持续”在其中一个线程中。 ? Sleep(0) 的意思是:把控制权交给另一个可用线程,由于我们只有2个线程,我不希望它应该连续写两次Console.WriteLine("This is supposedly the main thread.");
    • Console.WriteLine("main thread."); Thread.Sleep(0); 我理解是输出“主线程”,控制权被另一个线程声明,然后在另一个线程完成或放弃/放弃控制后返回这里。跨度>
    • 我相信 Thread.sleep(0) 不会强制将控制权交给其他线程,相反,它实际上只是向其他线程发出信号,表明如果您想开始,我愿意放弃轮到我。真正严格控制顺序的唯一方法是,您需要通过基于令牌的线程模型,以便在具有令牌的线程上可以执行。这样你就知道你可以控制获得令牌来处理的顺序。
    猜你喜欢
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多