Различия в разных способах создания параллельных программ - PullRequest
10 голосов
/ 30 апреля 2010

В чем разница между:

  1. Начало новой темы
  2. Использование TPL
  3. Использование BackgroundWorker

Все это создает параллелизм, но каковы различия между этими уровнями? Все 3 делают темы в любом случае?

Спасибо

Ответы [ 3 ]

19 голосов
/ 30 апреля 2010

Все они используют потоки внутри, различия связаны с уровнем абстракции каждого API и тем, как используются потоки. Давайте немного переупорядочим ваш список и рассмотрим три метода от самого низкого до самого высокого уровня абстракции:

  1. Запуск новой темы вручную :

    Это фактически создает новый поток в ОС. Ваш код будет выполнен в этом потоке.

  2. Использование BackgroundWorker :

    Внутренне для этого используется нечто, называемое .net ThreadPool . Пул потоков - это в основном пул доступных потоков. Ваш код назначен одному из доступных потоков и выполняется в этом потоке.

    Пул управляет количеством доступных потоков и будет внутренне создавать и уничтожать потоки по мере необходимости в определенных пределах. Это полезно, потому что пул может иметь несколько алгоритмов для оптимизации создания потоков. Создание потоков - довольно дорогой процесс, поэтому, если необходимо, пул потоков поддерживает потоки и использует их для будущих запросов. Вы можете иметь некоторый ограниченный контроль над пулом, указав минимальное / максимальное количество потоков и некоторые незначительные изменения, подобные этому.

    Существуют и другие способы непосредственного использования ThreadPool, например QueueUserWorkItem (...) .

  3. Использование параллельной библиотеки задач :

    Это еще более высокая абстракция. Вы создаете «задачи» и говорите TPL, чтобы они выполнялись. TPL скрывает все опасения относительно того, сколько именно потоков и какие приоритеты будут использоваться и т. Д. TPL имеет возможность повторно использовать потоки и управлять ими в зависимости от производительности конкретной машины и доступных ресурсов ЦП.

    Например, при задании 100 задач в четырехъядерном ядре TPL может порождать 4 потока, а в 8-ядерном - 8 и распределять задачи по доступным потокам по завершении каждой задачи.

Итак, чтобы ответить на ваш вопрос. Все 3 техники используют потоки, но по мере того, как вы поднимаетесь на каждый уровень, уровень контроля и осведомленности об этих потоках уменьшается.

В большинстве случаев я бы порекомендовал вам использовать TPL. Если вам не нужен конкретный, очень точный контроль над количеством потоков и их созданием / уничтожением, TPL справится со всем этим очень хорошо для вас.

3 голосов
/ 30 апреля 2010
  1. Начало новой темы является самым дорогим из трех вариантов, но вы получаете большинство возможностей. Как установить модель квартиры и приоритет.

  2. Библиотека параллельных задач будет запускать задачу в ThreadPool (если только задача не помечена как нужная для своего собственного потока) и добавляет функцию обработки исключений и функцию ожидания завершения. 1012 *

  3. BackgroundWorker полезен только для запуска задач, порожденных из WinForms или WPF. Также используется Threadpool

  4. Дополнительно: ThreadPool . Используется для выполнения коротких задач без накладных расходов на создание отдельного потока.

2 голосов
/ 30 апреля 2010

Создание потока - это просто ... вы создаете один поток для одновременного выполнения с основным потоком процесса.

В TPL, если вы создадите задачу, она будет использовать пул потоков, чтобы найти свободный поток для запуска задачи. Это может быть более эффективным, когда вы создаете много задач, потому что TPL способен балансировать нагрузку между любым количеством свободных потоков (предположительно, количество потоков сбалансировано на основе количества ядер, которые у вас есть, но я точно не знаю этого. )

Наконец, BackgroundWorker запускает вашу работу в отдельном потоке. Это действительно просто хорошая абстракция, которая удаляет вас из грязных частей потоков, так как она управляется для вас. Это также обеспечивает способ отослать обновления статуса, если я не ошибаюсь. (не уверен, использует ли он пул потоков Windows, но я не удивлюсь)

В конце концов, вы должны выбрать то, что подходит для вашей программы, но цель TPL Tasks состоит в том, чтобы позволить вам эффективно планировать задачи, которые могут выполняться параллельно, тогда как создание потоков или использование фоновых рабочих может быть лучше на долгое время выполнение операций или для сценариев, в которых вы хотите, чтобы фоновый поток жил вечно в ожидании какого-либо сигнала (в действительности я бы предложил использовать RegisteredWait, если вы просто ожидаете какого-то события).

...