C# 为什么这个线程示例根本不可预测(每次输出不同的结果)?

C# 为什么这个线程示例根本不可预测(每次输出不同的结果)?,c#,multithreading,thread-sleep,C#,Multithreading,Thread Sleep,我正在努力学习线程。因此,我在一本官方书籍中发现了这篇文章: 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.S

我正在努力学习线程。因此,我在一本官方书籍中发现了这篇文章:

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();
    }
}
但是,每次运行控制台应用程序时,实际结果都不一样,为什么? 其次,我希望首先在屏幕上看到“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
还有一个:

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

这是因为程序中有两个线程,一个是执行main方法的主线程,另一个是在这个主方法中创建的执行ThreadMethod的线程。这两个线程正在访问一个公共输出,在本例中,这是您的控制台,操作系统可以选择按任何顺序安排访问。这就是为什么如果您多次运行此程序,每次都会得到它们之间的不同顺序。日程安排超出了程序的控制范围

这是因为程序中有两个线程,一个是执行main方法的主线程,另一个是在这个主方法中创建的执行ThreadMethod的线程。这两个线程正在访问一个公共输出,在本例中,这是您的控制台,操作系统可以选择按任何顺序安排访问。这就是为什么如果您多次运行此程序,每次都会得到它们之间的不同顺序。日程安排超出了程序的控制范围

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

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


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

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

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


另外,您在控制台上看到的内容可能会让人困惑,但从这个角度看,线程是异步运行的,这意味着如果两个进程同时运行
Console.WriteLine
,cpu仍然需要根据cpu的调度方式来决定首先显示哪个输出。

在书中,有一段代码是他们输出结果的代码,但没有声明这是一个可能的输出,并且不是每次都呈现相同的结果。所以它误导了我。非常感谢。所以我理解你所说的优先级,但是一旦CPU决定哪个是优先级,为什么它会在线程之后的一个线程中“持续”呢?Sleep(0)?Sleep(0)的意思是:控制另一个可用的线程,因为我们只有2个线程,所以我不希望它写
Console.WriteLine(“这应该是主线程”)连续两次。
Console.WriteLine(“主线程”);睡眠(0)我由此理解,“主线程”被输出,控制权由另一个线程声明,然后在另一个线程完成或放弃/放弃控制后返回此处。我相信thread.sleep(0)不会强制将控制权交给另一个线程,相反,它实际上只是在暗示另一条线索,如果你愿意开始,我愿意放弃我的回合,如果你可以的话。真正严格控制顺序的唯一方法是,您需要通过基于令牌的线程模型,以便在具有令牌的线程上执行。通过这种方式,您知道您可以控制获得要处理的令牌的顺序。在书中,有他们输出结果的代码,但没有声明这是一种可能的输出,并且不是每次都呈现相同的结果。所以它误导了我。非常感谢。所以我理解你所说的优先级,但是一旦CPU决定哪个是优先级,为什么它会在线程之后的一个线程中“持续”呢?Sleep(0)?Sleep(0)的意思是:控制另一个可用的线程,因为我们只有2个线程,所以我不希望它写
Console.WriteLine(“这应该是主线程”)连续两次。
Console.WriteLine(“主线程”);睡眠(0)我由此理解,“主线程”被输出,控制权由另一个线程声明,然后在另一个线程完成或放弃/放弃控制后返回此处。我相信thread.sleep(0)不会强制将控制权交给另一个线程,相反,它实际上只是在暗示另一条线索,如果你愿意开始,我愿意放弃我的回合,如果你可以的话。真正严格控制顺序的唯一方法是,您需要通过基于令牌的线程模型,以便在具有令牌的线程上执行。通过这种方式,您知道您可以控制获得要处理的令牌的顺序。bolov,您可以在书籍摘录/代码片段中看到很多次,在该摘录的下面是输出。没有免责声明,在这种情况下,输出实际上是可能的输出之一。它之前提到线程可以被优先排序,但是没有将这个想法与它们给出的示例联系起来。bolov,你在书中的很多节选/代码片段中都可以看到,在节选的下面是输出。没有免责声明