Как реализован новый PowerShell 7 ForEach-Object Parallel?

В PowerShell 7 появилась столь необходимая функция для параллельного выполнения конвейерного ввода.

Документация для PowerShell 7 не предоставляет подробных сведений о том, как это реализовано.

Раньше я использовал модули PoshRSJob и Invoke-Parallel, поэтому я знаю, что пространства выполнения традиционно считались гораздо более эффективным подходом для параллельных операций в PowerShell, а не для выполнения заданий PowerShell. Я читал смешанный контент, указывающий, что сейчас используется потоки, а не пространства выполнения, но не могу найти ничего особенного.

Я был бы очень признателен за некоторые технические подробности:

  1. Каков жизненный цикл выполнения с точки зрения .NET
  2. Это новые функциональные возможности: пространства выполнения или потоки? (или пространство выполнения - это просто поток .NET в System.Management.Automation?)
  3. Приносит ли это какую-либо сложность в традиционную отладку теперь, когда мы переходим к параллельным операциям? Раньше у меня были проблемы с отладкой с помощью пространств выполнения, и я не знал, какие параметры можно было бы улучшить

person sheldonhull    schedule 24.03.2020    source источник
comment
согласно статьям, которые я видел, он использует пространства выполнения. вам нужно отправить туда $ vars [обычно с $Using:]. он загружает все необходимые модули, функции и многое другое в каждое пространство выполнения, поэтому требуется время, чтобы настроить и отключить. Я пока ничего не видел об отладке.   -  person Lee_Dailey    schedule 24.03.2020
comment
Отдельные пространства выполнения, управляемые через новый внутренний API (PSTaskPool). RFC описывает некоторые детали реализации и ограничений. также содержит ряд полезных комментариев   -  person Mathias R. Jessen    schedule 24.03.2020
comment
На всякий случай (кто знает) есть также SplitPipeline с некоторыми уникальными функциями (ИМХО, действительно), например он хорошо работает с очень большим или бесконечным вводом.   -  person Roman Kuzmin    schedule 24.03.2020
comment
Также есть задание start-threadjob, которое, как мне кажется, было написано тем же парнем. Он не сериализует такие объекты, как start-job.   -  person js2010    schedule 24.03.2020
comment
Мне также указали на RFC с некоторой отличной информацией. Просмотрите и опубликуйте здесь ответ, если он ответит на некоторые из этих вопросов позже. Параллельный командлет   -  person sheldonhull    schedule 25.03.2020


Ответы (2)


Отладка foreach-object -parallel:

Для этого мне нужен второй процесс pwsh. В первом:

foreach-object -parallel { Wait-Debugger;1;2;3 }

Затем во втором окне выясните, что такое pid другого pwsh. Затем введите этот pshostprocess. Посмотрите на области выполнения и отладьте ту, доступность которой говорит «InBreakpoint». «v» означает «перешагнуть».

get-process pwsh

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
     64    44.32      82.23       1.70    3912  12 pwsh
     63    40.66      78.03       1.36    6472  12 pwsh

$pid
6472

Enter-PSHostProcess 3912

get-runspace

 Id Name            ComputerName    Type          State         Availability
 -- ----            ------------    ----          -----         ------------
  1 Runspace1       localhost       Local         Opened        Busy
  2 PSTask:1        localhost       Local         Opened        InBreakpoint
  3 RemoteHost      localhost       Local         Opened        Busy

debug-runspace 2
v
v
v

Если вы запустите foreach-object -parallel -asjob, вы можете использовать get-runspace и debug-runspace в одном окне. Но вы не могли видеть результат при шаге.

foreach-object -parallel { Wait-Debugger;1;2;3 } -asjob
get-runspace

 Id Name            ComputerName    Type          State         Availability
 -- ----            ------------    ----          -----         ------------
  1 Runspace1       localhost       Local         Opened        Available
  2 PSTask:1        localhost       Local         Opened        InBreakpoint

debug-runspace 2
v
v
v

Вот новое видео отладки, в котором есть некоторые расширенные настройки с помощью Vscode: https://www.reddit.com/r/PowerShell/comments/gn0270/advanced_powershell_debugging_techniques/

person js2010    schedule 20.05.2020

Нашел этот фантастический пост в блоге PowerShell ForEach-Object Parallel Feature автора Пол Хигинботэм.

Из этого сообщения в блоге я вынес ключевые моменты:

Блоки сценариев выполняются в контексте, называемом пространством выполнения PowerShell. Контекст пространства выполнения содержит все определенные переменные, функции и загруженные модули.

Как упоминалось ранее, новая функция ForEach-Object -Parallel использует существующие функциональные возможности PowerShell для одновременного запуска блоков сценариев ... Сама оболочка PowerShell налагает условия на то, как сценарии выполняются одновременно, в зависимости от своего дизайна и истории. Сценарии должны выполняться в контекстах пространства выполнения, и только один поток сценария может выполняться одновременно в пространстве выполнения. Таким образом, для одновременного запуска нескольких сценариев необходимо создать несколько пространств выполнения.

Таким образом, он подтверждает, что пространства выполнения являются основным драйвером для этого, и предоставляет дополнительную информацию о потокобезопасных операциях и многом другом. Любые предыдущие ответы или подробности, представленные о пространствах выполнения, актуальны здесь, поскольку это зрелая реализация пространств выполнения для параллельных операций в официальной стандартной библиотеке. Другие реализации были выполнены сообществом, ориентированными на пространство выполнения, но теперь они включены без каких-либо зависимостей от внешних модулей.

Спасибо, Пол за такой хороший вклад в сообщество! ????

person sheldonhull    schedule 08.05.2020
comment
Я не думаю, что ты сможешь. Пространства выполнения являются многопоточными, поэтому не уверен, что вы можете разбить их на отдельные пространства выполнения с помощью отладчика. У меня никогда не было успеха, поэтому дайте мне знать, если вы узнаете иначе. Похоже, может быть, хороший отдельный вопрос - person sheldonhull; 14.05.2020
comment
есть команда debug-runspace. Но вам, возможно, придется прервать работу другого процесса, если цикл каким-то образом не работает в фоновом режиме. - person js2010; 14.05.2020