PowerShell: Script vomitando en paralelo

PowerShell: Script vomitando en paralelo

Cuando se ejecuta en -Parallel, el siguiente script no pasa la $basePathvariable declarada antes del inicio del bloque paralelo. En cambio, es un valor nulo. Esto no es un problema cuando el script no se ejecuta -Parallel: pasará el valor de la variable y se ejecutará como se esperaba. Para su información, estoy ejecutando PS 7.x.

$basePath=((get-location) -replace "\\", "\\")
get-childitem *.tif -recurse | foreach-object -Parallel {
    $a=($_ -split "\.tif")[0]
    $path=(((split-path $_) -replace "$basePath", "O:\OD\FM\OneDrive\FM\Family Photos") -replace "TIF", "JPG")
    $b=(($a -replace "$basePath", "O:\OD\FM\OneDrive\FM\Family Photos") -replace "TIF", "JPG")
    if (!(Test-Path -path $path)) {mkdir "$path"}
    if (!([system.io.file]::Exists("$b.jpg"))) {
        magick convert "$a.tif" -resize 50% -quality 100 -define jpeg:extent=1024KB "$b.jpg"
        [console]::foregroundcolor="Green"
        echo "`nB`:`t$b`n`n"
    }
} -ThrottleLimit 8
    [console]::foregroundcolor="White"

Respuesta1

Entonces, en el nuevo -parallelesquema de PowerShells, debe usarlo $using:basePathen lugar de solo $basePathpara todas las invocaciones dentro del bucle paralelo. Esto se debe a que la variable está definida en un ámbito principal.

Las operaciones paralelas y de subprocesos múltiples presentan un conjunto único de complicaciones denominadas colectivamente simultaneidad o problemas multiconcurrentes y, por lo tanto, requieren que se tomen medidas especiales para garantizar que la memoria a la que acceden los subprocesos esté en un estado seguro para su uso.

Powershell implementa un contexto de subprocesos llamado RunSpace y crea uno para cada operación paralela. El espacio de ejecución contiene una copia de cada variable declarada en ese bloque y solo puede operar en aquellas instancias copiadas de las variables. esto significa que si un hilo modifica su versión de la variable, otros hilos no verán ese cambio.

Sin embargo, para acceder a una variable que está dentro del alcance de múltiples subprocesos, debemos analizar técnicas como Mutex y Locks. Un bloqueo de subproceso es una construcción simple que evita que un valor se modifique mientras se utiliza. En Powershell, lo hicieron fácil agregando la $using:palabra clave para hacer referencia a variables de mayor alcance.

Consulte aquí para obtener más detalles:https://devblogs.microsoft.com/powershell/powershell-foreach-object-parallel-feature/

información relacionada