C# Join()更改C中的程序输出

C# Join()更改C中的程序输出,c#,multithreading,C#,Multithreading,简而言之,这是C中给出的一个示例程序的稍微修改版本: using System; using System.Threading; namespace SemaphorTest { class Program { static Semaphore gate = new Semaphore(3, 3); static void Main(string[] args) { for (int i = 0; i &l

简而言之,这是C中给出的一个示例程序的稍微修改版本:

using System;
using System.Threading;

namespace SemaphorTest
{
    class Program
    {
        static Semaphore gate = new Semaphore(3, 3);
        static void Main(string[] args)
        {
            for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(Enter);
                t.Start(i);
            }
        }

        public static void Enter(Object id)
        {
            Console.WriteLine("Thread " + id + " wants to enter.");
            gate.WaitOne();
            Console.WriteLine("Thread " + id + " is in.");
            Thread.Sleep(500 * (Int32)id);
            Console.WriteLine("Thread " + id + " leaving.");
            gate.Release();
        }
    }
}
但是,按如下方式添加Thread.Join会显著更改输出。即:

for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(Enter);
                t.Start(i);
                t.Join();
            }
为什么会发生这种情况?我知道默认情况下,这些线程是前台线程,主线程不需要等待它们完成,即使在主线程完成后,它们也会运行,因此它们不需要线程。在这里加入。但我不明白是什么让它们按顺序运行,因为它们是在更改后创建的。有什么想法吗

Thanks
Dileep Balakrishnan 

您正在将每个线程与调用线程连接。这实际上会阻塞调用线程,并等待每个线程依次结束

在报告中指出:

阻止调用线程,直到线程终止


您正在将每个线程与调用线程连接。这实际上会阻塞调用线程,并等待每个线程依次结束

在报告中指出:

阻止调用线程,直到线程终止

为什么会发生这种情况

因为是你要求的

您启动了一个线程,然后等待它完成,然后启动了下一个线程等等。这正是thread.Join所做的:它会阻止当前正在执行的线程,直到您调用它的线程终止

我感兴趣的是你期望代码做什么。。。如果您只是想等到所有线程都完成后再让主线程完成,那么您需要启动所有线程,在运行时记住它们,然后依次调用Join。例如:

List<Thread> threads = new List<Thread>();
// First start all the threads
for (int i = 0; i < 5; i++)
{
    Thread t = new Thread(Enter);
    t.Start(i);
    threads.Add(t);
}

// Then wait for them to finish
foreach (var thread in threads)
{
    thread.Join();
}
为什么会发生这种情况

因为是你要求的

您启动了一个线程,然后等待它完成,然后启动了下一个线程等等。这正是thread.Join所做的:它会阻止当前正在执行的线程,直到您调用它的线程终止

我感兴趣的是你期望代码做什么。。。如果您只是想等到所有线程都完成后再让主线程完成,那么您需要启动所有线程,在运行时记住它们,然后依次调用Join。例如:

List<Thread> threads = new List<Thread>();
// First start all the threads
for (int i = 0; i < 5; i++)
{
    Thread t = new Thread(Enter);
    t.Start(i);
    threads.Add(t);
}

// Then wait for them to finish
foreach (var thread in threads)
{
    thread.Join();
}

Thread.join不会使事物同时运行。它实际上通过阻止当前线程直到其完成来强制执行您看到的行为。
文档中明确提到了这一点:

Thread.join不会使事情同时运行。它实际上通过阻止当前线程直到其完成来强制执行您看到的行为。
文档中明确提到了这一点:

连接使其成为一个单线程应用程序。连接使其表现为一个单线程应用程序app@spender-说明t.开始;t、 加入;为任何多线程处理留出的空间非常少。智能抖动甚至可能会优化它。连接使其成为单线程应用程序。连接使其表现为单线程app@spender-说明t.开始;t、 加入;为任何多线程处理留出的空间非常少。聪明的抖动甚至可以优化这一点。有趣的是,我写的代码与您在阅读博文后指出的相同,当然,没有您的评论:。不管怎样,谢谢。有趣的是,我写的代码与你在阅读博文后指出的一样,当然没有你的评论:。无论如何,谢谢你。
List<Thread> threads = new List<Thread>();
// First start all the threads
for (int i = 0; i < 5; i++)
{
    Thread t = new Thread(Enter);
    t.Start(i);
    threads.Add(t);
}

// Then wait for them to finish
foreach (var thread in threads)
{
    thread.Join();
}