【问题标题】:What happens to the main thread in this case在这种情况下主线程会发生什么
【发布时间】:2012-03-22 07:02:23
【问题描述】:

我有以下多线程程序:

class Program{
  static void main(){
    (new Thread(DoSomething)).Start();
  }
  static void DoSomething(){
    // Dome something here...
  }
}

几个问题:

  1. 子线程分离后主线程是否退出?
  2. 如果它退出并且子线程是后台线程:主进程是要退出还是等待后台线程完成?

【问题讨论】:

  • 添加Console.Write 自己看看
  • 问题 #2 有点多余。你首先问它是否只是要退出,然后你问它是否退出:“它退出”还是“它等待”?好吧,如果它退出,那么它就会退出。
  • @jlafay 子线程是否是背景是有区别的:)因此问题
  • 主线程没有区别。无论如何它都会退出。
  • 不管怎样,主线程可能会退出,但如果线程在前台,进程不会立即退出。您可以快速运行我在下面的答案中发布的代码,向自己证明这一点。他在第二个问题中指定了“进程”,而不是“线程”。

标签: c# .net multithreading


【解决方案1】:

“默认情况下,您显式创建的线程是前台线程。只要其中任何一个正在运行,前台线程就会使应用程序保持活动状态,而后台线程则不会。一旦所有前台线程完成,应用程序就会结束,并且任何仍在运行的后台线程突然终止。

class PriorityTest
{
    static void Main (string[] args)
    {
        Thread worker = new Thread ( () => Console.ReadLine() );
        if (args.Length > 0) worker.IsBackground = true;
        worker.Start();
    }
}

如果在没有任何参数的情况下调用此程序,则工作线程将处于前台状态并等待 ReadLine 语句让用户按 Enter。同时,主线程退出,但应用程序继续运行,因为前台线程仍然存在。

但是,如果将参数传递给 Main(),则会为工作线程分配后台状态,并且程序几乎会在主线程结束时立即退出(终止 ReadLine 和程序)。"

有关更多信息,请参阅Joseph Albahri's (a genius and great guy) page 线程(这是从中提取的)。

【讨论】:

    【解决方案2】:

    通常,如果您想等待子线程完成,您会在您希望主线程停止并等待子线程停止的任何地方添加 x.Join(); 行(其中 x 是线程的变量)完全的。

    编辑:所以,是的,除非发生以下三种情况之一,否则主线程将退出: a) 生成的线程在其余的主线程代码之前完成(如果您添加了任何代码)

    b) 你有一个等待线程完成的条件(比如我提到的 Join 语句,但也有其他方法)。

    c) 主线程进入半无限循环(如游戏/图形引擎)。

    在您的简单示例中,它肯定会退出(给定您问题的参数,一个后台线程)。

    EDIT2:对不起,我似乎回避了你的第二个问题(实际上一直只考虑后台线程)。如果它是后台线程,它会像我解释的那样退出,如果它是前台,那么它不应该(尽管我对前台线程没有太多经验,所以我不能肯定地说)。

    所以回答你的问题:是的,主线程退出。是的,如果子进程是特定的后台线程,进程也会退出。

    EDIT3:我保证是最终编辑。我只是想添加一些代码,以便您可以自己证明答案(能够做到这一点总是很好):

    static void Main(string[] args)
    {
        Thread thready = new Thread(DoSomething);
        thready.IsBackground = true;
        thready.Start();
    }
    
    static void DoSomething()
    {
        while (true)
        {
            Console.Write("thread's looping \n");
        }
    }
    

    通过将thready.IsBackground = true; 切换到thready.IsBackground = false;,您将获得一个永远运行的程序(直到线程运行才退出)。将其保留为 true 将很快退出。

    【讨论】:

      【解决方案3】:

      取决于Thread.IsBackground

      在所有前台线程完成之前,该进程不会退出。在下面的例子中......

      class Program {
      
          static void Main(string[] args) {
              (new Thread(DoSomething)).Start();
          }
      
          static void DoSomething() {
              Thread.Sleep(5000);
          }
      
      }
      

      ...进程将在 5 秒后退出。

      但在这个例子中...

      class Program {
      
          static void Main(string[] args) {
              (new Thread(DoSomething) { IsBackground = true }).Start();
          }
      
          static void DoSomething() {
              Thread.Sleep(5000);
          }
      
      }
      

      ...进程将(几乎)立即退出。对仍在运行的子后台线程的影响类似于强制终止进程,因此请尽可能避免这样做。

      【讨论】:

        【解决方案4】:

        主进程线程肯定会退出...

        编辑:我重新检查了文档,发现 IsBackground 属性默认为 false...这意味着主线程将等待...关于第二个问题的较早响应 ws

        【讨论】:

        • 为什么?它将被自动创建为前台线程,这将导致父/主线程等待,直到它完成它的工作......
        猜你喜欢
        • 1970-01-01
        • 2017-08-19
        • 1970-01-01
        • 2011-04-16
        • 2021-01-24
        • 1970-01-01
        • 1970-01-01
        • 2013-08-02
        • 2018-12-19
        相关资源
        最近更新 更多