繁体   English   中英

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

[英]Is background thread only executed when the number of foreground threads executing is smaller than the number of processors?

根据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%.
...

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

我认为该陈述是不正确的,此外,您使用的不是最新版本的文档。 如果您查找有关托管线程/前台和后台线程 的文档最新版本,则会显示:

托管线程可以是后台线程,也可以是前台线程。 后台线程与前台线程相同,但有一个例外:后台线程不能使托管执行环境保持运行状态。 一旦所有前台线程都已在托管进程中停止(.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类配置线程池并安排线程池线程上的工作。

    注意

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM