Parallele Ausführung einer großen Anzahl kleiner Jobs in Windows mit Timeout-Funktion

390
Mattia Landoni

Ich muss> 50.000 Dateien mit einer .exe-Befehlszeilenanwendung eines Drittanbieters verarbeiten. Die Anwendung benötigt jeweils nur eine Eingabedatei, daher muss ich die Anwendung> 50.000-mal starten.

Jede Datei (jeder Job) dauert normalerweise etwa eine Sekunde. Manchmal hängt die Anwendung jedoch auf unbestimmte Zeit.

Ich habe ein Windows-Shell-Skript geschrieben, das alle Jobs seriell ausführt und jede Sekunde überprüft, ob der Job erledigt ist. Nach 10 Sekunden wird der Job abgebrochen und der nächste Job ausgeführt. Es dauert jedoch ungefähr 20 Stunden. Ich glaube, ich kann die Gesamtlaufzeit erheblich reduzieren, wenn mehrere Jobs parallel ausgeführt werden. Die Frage ist wie?

In CMD starte ich die Task mit Start, aber es gibt keine einfache Möglichkeit, die Prozess-ID (PID) wiederherzustellen. Daher kann ich nicht leicht nachvollziehen, welche Instanz wie lange gelaufen ist. Ich habe das Gefühl, ich versuche den Regenschirm neu zu erfinden. Irgendwelche Vorschläge?

1
Fragen, die nach Produkt-, Service- oder Lernmaterialempfehlungen suchen, sind unangebracht, da sie schnell veraltet sind und auf Meinungen basierende Antworten finden. Beschreiben Sie stattdessen Ihre Situation und das spezifische Problem, das Sie lösen möchten. Teilen Sie Ihre Forschung mit. Xavierjazz vor 6 Jahren 0
Ich habe mein Problem ausführlich im Beitragstitel und in den ersten beiden Absätzen beschrieben. Der dritte Abschnitt beschreibt, was ich getan habe. Ich habe den vierten Absatz geändert, weiß aber nicht, dass die Frage jetzt besser ist. Mattia Landoni vor 6 Jahren 0

2 Antworten auf die Frage

2
Mattia Landoni

Powershell machte den Trick, wie in der Vierfachbuckys Antwort angegeben. Hier ist der Code, den ich verwendet habe. Die vorletzte Zeile ( ./xml2csv...) ist der Job selbst. Der Rest des Skripts kann für ähnliche Aufgaben wiederverwendet werden.

# PARAMETERS $root = 'D:\Ratings' $folder = 'SP'  # Import Invoke-Parallel .".\Invoke-Parallel.ps1"  # Run in parallel Get-ChildItem ".\$folder-xml" -Filter *.xml | Invoke-Parallel -throttle 10 -runspaceTimeout 10 -ImportVariables ` -ScriptBlock { $file = $_.BaseName echo $file cd $root (./xml2csv $folder-xml\$file.xml $folder-csv\$file.csv fields-$folder.txt -Q) | out-null } 

Einige Notizen:

  • Die Invoke-Parallel-Funktion (auch bekannt als Cmdlet ) kann hier heruntergeladen werden .
  • Ein Runspace ist das, was ich als "Instanz" bezeichnet hätte. -runspaceTimeoutgibt die maximale Laufzeit für jede Instanz an.
  • -throttle Legt die maximale Anzahl gleichzeitig laufender Instanzen fest.
0
quadruplebucky

Powershell ist dein Freund.

https://serverfault.com/questions/626711/how-do-i-run-my-powershell-scripts-in-parallel-without-using-jobs fragt etwas Ähnliches.

"Schnell" und "robust" sind natürlich subjektiv.

Danke, Powershell ist das, was ich brauchte. Ich füge unten eine Antwort mit dem genauen Code hinzu, den ich verwendet habe, was meiner Meinung nach sehr wiederverwendbar ist. Ich habe das "Invoke-Parallel" -Tool in der Antwort verwendet, auf die Sie gezeigt haben. Mattia Landoni vor 6 Jahren 1
Ich habe auch "quick" und "robust" aus dem Titel entfernt. Vielen Dank Mattia Landoni vor 6 Jahren 0