Фоновый поток выполняется только тогда, когда количество выполняемых потоков переднего плана меньше числа процессоров? - PullRequest
0 голосов
/ 16 ноября 2018

Согласно docs.microsoft.com [ 1 , 2 , 3 , 4 ]:

Фоновый поток выполняется только тогда, когда количество выполняемых потоков переднего плана меньше, чем число процессоров.

Однако, если я запускаю 4 потока переднего плана на 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 голосов
/ 16 ноября 2018

По моему мнению, утверждение неверно, и, кроме того, вы смотрите не последнюю версию документации. Если вы посмотрите последнюю версию документации о Управляемые потоки / Передний план и Фоновые потоки , в ней будет указано:

Управляемый поток - это фоновый поток или поток переднего плана. Фоновые потоки идентичны приоритетным потокам с одним исключением: фоновый поток не поддерживает работу управляемой среды выполнения. Как только все приоритетные потоки были остановлены в управляемом процессе (где файл .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.

    Примечание

    Асинхронные операции на основе задач автоматически выполняются в потоках пула потоков.

  • Все потоки, которые входят в среду управляемого выполнения из неуправляемого кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...