仅在执行的前台线程数小于处理器数量时才执行后台线程吗?

时间:2018-11-15 23:18:12

标签: c# .net multithreading clr

根据docs.microsoft.com [1234]:

  

仅当执行的前台线程数小于处理器数量时,才会执行后台线程。

但是,如果我在4核CPU上启动4个前台线程(没有超线程),然后启动4个后台线程,则前台线程和后台线程将并排运行,这似乎与以下语句矛盾以上。

代码示例:

static void Main(string[] args)
{
    int numberOfProcessors = 4;

    for (int i = 0; i < numberOfProcessors; i++)
    {
        int threadNumber = i;

        new Thread(() =>
        {
            Console.WriteLine($"Foreground thread {threadNumber} started.");

            for (int j = 1; j <= 100; j++)
            {
                for (long k = 0; k < 10000000000; k++);

                Console.WriteLine($"Foreground thread {threadNumber} progress: {j}%.");
            }
        })
        .Start();
    }

    for (int i = 0; i < numberOfProcessors; i++)
    {
        int threadNumber = i;

        var backgroundThread = new Thread(() =>
        {
            Console.WriteLine($"Background thread {threadNumber} started.");

            for (int j = 1; j <= 100; j++)
            {
                for (long k = 0; k < 10000000000; k++);

                Console.WriteLine($"Background thread {threadNumber} progress: {j}%.");
            }
        });
        backgroundThread.IsBackground = true;
        backgroundThread.Start();
    }

    Console.ReadLine();
}

输出:

Foreground thread 1 started.
Foreground thread 0 started.
Foreground thread 3 started.
Foreground thread 2 started.
Background thread 0 started.
Background thread 1 started.
Background thread 2 started.
Background thread 3 started.
Foreground thread 2 progress: 1%.
Foreground thread 0 progress: 1%.
Foreground thread 1 progress: 1%.
Foreground thread 3 progress: 1%.
Background thread 1 progress: 1%.
Background thread 0 progress: 1%.
Background thread 2 progress: 1%.
Background thread 3 progress: 1%.
Foreground thread 0 progress: 2%.
Foreground thread 2 progress: 2%.
Foreground thread 1 progress: 2%.
Foreground thread 3 progress: 2%.
Background thread 0 progress: 2%.
Background thread 1 progress: 2%.
Background thread 3 progress: 2%.
Background thread 2 progress: 2%.
Foreground thread 0 progress: 3%.
Foreground thread 2 progress: 3%.
Foreground thread 1 progress: 3%.
Foreground thread 3 progress: 3%.
Background thread 1 progress: 3%.
Background thread 0 progress: 3%.
Background thread 3 progress: 3%.
Background thread 2 progress: 3%.
...

该陈述不正确吗?还是我只是弄错了?

1 个答案:

答案 0 :(得分:2)

我认为该陈述是不正确的,此外,您使用的不是最新版本的文档。如果您查找有关Managed Threading / Foreground and Background Threads文档的最新版本,则会显示:

  

托管线程是后台线程或前台线程。后台线程与前台线程相同,但有一个例外:后台线程不能使托管执行环境保持运行。一旦所有前台线程都在托管进程(其中.exe文件是托管程序集)中停止,系统将停止所有后台线程并关闭。

     

注意

     

当运行时由于进程正在关闭而停止后台线程时,该线程中不会引发任何异常。但是,当由于AppDomain.Unload方法卸载应用程序域而停止线程时,前台线程和后台线程都会抛出ThreadAbortException。

     

使用Thread.IsBackground属性确定线程是后台线程还是前台线程,或更改其状态。通过将其IsBackground属性设置为true,可以随时将线程更改为后台线程。

     

重要

     

线程的前台或后台状态不会影响线程中未处理的异常的结果。在.NET Framework 2.0版中,前台线程或后台线程中未处理的异常会导致应用程序终止。请参阅托管线程中的异常。

     

属于托管线程池的线程(即,IsThreadPoolThread属性为true的线程)是后台线程。从非托管代码进入托管执行环境的所有线程都被标记为后台线程。默认情况下,通过创建和启动新的Thread对象生成的所有线程都是前台线程。

     

如果您使用线程来监视活动(例如套接字连接),请将其IsBackground属性设置为true,以便该线程不会阻止您的进程终止。



Thread.IsBackground属性的文档也是如此:

  

备注

     

线程是后台线程或前台线程。 除了后台线程不会阻止进程终止之外,后台线程与前台线程相同。一旦属于某个进程的所有前台线程都终止,则公共语言运行库将终止该进程。其余的所有后台线程都将停止并且无法完成。

     

默认情况下,以下线程在前台执行(即,其IsBackground属性返回false):

     
      
  • 主线程(或主应用程序线程)。
  •   
  • 通过调用Thread类构造函数创建的所有线程。
  •   
     

默认情况下,以下线程在后台执行(即,其IsBackground属性返回true):

     
      
  • 线程池线程,是运行时维护的工作线程池。您可以使用ThreadPool类配置线程池并安排线程池线程上的工作。

         

    注意

         

    基于任务的异步操作自动在线程池线程上执行。

  •   
  • 所有从非托管代码进入托管执行环境的线程。

  •