Parallel Extensions — название разработки для библиотеки управляемого параллелизма , разработанной в сотрудничестве между Microsoft Research и командой CLR в Microsoft . Библиотека была выпущена в версии 4.0 .NET Framework . [1] Она состоит из двух частей: Parallel LINQ (PLINQ) и Task Parallel Library (TPL). [2] [3] Она также состоит из набора структур данных координации (CDS) — наборов структур данных, используемых для синхронизации и координации выполнения параллельных задач. [4]
PLINQ или Parallel LINQ , распараллеливающий выполнение запросов к объектам (LINQ to Objects) и XML-данным (LINQ to XML). PLINQ предназначен для раскрытия параллелизма данных с помощью запросов. [2] Любое вычисление над объектами, реализованное как запросы, может быть распараллелено PLINQ. Однако объекты должны реализовывать интерфейс IParallelEnumerable
, который определяется самим PLINQ. Внутренне он использует TPL для выполнения. [4] [5]
Библиотека параллельных задач ( TPL ) — это компонент параллелизма задач Parallel Extensions для .NET. [6] Она предоставляет параллельные конструкции, такие как parallel For
и ForEach
loops, используя обычные вызовы методов и делегатов , поэтому конструкции могут использоваться из любых языков CLI . Работа по созданию и завершению потоков , а также масштабирование количества потоков в соответствии с количеством доступных процессоров выполняется самой библиотекой, [3] используя планировщик захвата работы . [7]
TPL также включает другие конструкции, такие как Task и Future . Task — это действие, которое может быть выполнено независимо от остальной части программы. В этом смысле оно семантически эквивалентно потоку, за исключением того, что это более легкий объект и не требует дополнительных затрат на создание потока ОС. Задачи ставятся в очередь объектом Task Manager и планируются для выполнения в нескольких потоках ОС в пуле потоков, когда приходит их очередь.
Future — это задача, которая возвращает результат. Результат вычисляется в фоновом потоке, инкапсулированном объектом Future , и результат буферизуется до тех пор, пока не будет извлечен. [3] Если будет предпринята попытка извлечь результат до того, как он был вычислен, то запрашивающий поток будет заблокирован до тех пор, пока результат не станет доступен. [6]
Другая конструкция TPL — это класс Parallel . TPL обеспечивает базовую форму структурированного параллелизма посредством трех статических методов в классе Parallel:
Основная концепция в Parallel Extensions to .NET — это Task
, который представляет собой небольшую единицу кода, обычно представленную как лямбда-функция , которая может быть выполнена независимо. И PLINQ, и TPL API предоставляют методы для создания Tasks — PLINQ делит запрос на более мелкие Tasks, а методы Parallel.For
, Parallel.ForEach
и Parallel.Invoke
делят цикл на Tasks.
PFX включает Task Manager
объект, который планирует выполнение задач. Диспетчер задач содержит глобальную очередь задач, которые затем выполняются. Он также инкапсулирует несколько потоков , в которых выполняются задачи. По умолчанию создается столько потоков, сколько процессоров (или ядер процессора) в системе, хотя это число можно изменить вручную. Каждый поток связан с очередью задач, специфичной для потока. В состоянии бездействия каждый поток берет пакет задач и помещает их в свою локальную очередь, где они затем выполняются одна за другой. Если глобальная очередь пуста, поток будет искать задачи в очередях своих одноранговых узлов и брать задачи, которые находились в очереди дольше всего ( захват задач ). Во время выполнения задачи будут выполняться независимо, при этом изменение состояния одной задачи будет независимым от других. В результате, если они используют общий ресурс, их все равно нужно будет синхронизировать вручную с помощью блокировок или других конструкций.