Wenn Sie mehrere Hintergrundprozesse gleichzeitig ausführen, warten Sie unter Windows, bis alle beendet sind

14

Weiß jemand, ob es ein Cmd-Skript gibt, das dies tut, und / oder ein Befehlszeilenprogramm, das für den Job bereit ist?

Sergio
quelle
Dies kann Ihren Daten schaden!
Santosh Kumar
8
@ Santosh: Was meinst du mit "kann deine Daten schädigen"? In meinem speziellen Fall würden die Hintergrundaufgaben ihre eigenen unabhängigen Datensätze verarbeiten. Keine Risiken gleichzeitiger Änderungen.
Sergio
1
Von der Win32-API-Seite denke ich, dass WaitForMultipleObjects mit bWaitAll = TRUE den Job machen würde. Es wäre nicht schwer, ein Programm zu schreiben, das nur die in einer Eingabedatei angegebenen Programme abschneidet, wenn es keine zufriedenstellenden Antworten gibt.
user1686
1
@grawity: Ja, ich habe vor, genau das zu tun, wenn nichts auftaucht (und den Code hier posten), aber mal sehen, ob ich es vermeiden kann, das Rad neu zu erfinden :)
Sergio
Das Rad neu zu erfinden ist eine gute Sache, wenn derzeit vorhandene Räder quadratisch sind ...
user1686

Antworten:

10

Erstellen Sie die drei folgenden Batchdateien. Main.bat startet 1.bat und 2.bat

1.bat und 2.bat schreiben temporäre Dateien aus, nach denen main.bat sucht. Während 1.bat und 2.bat arbeiten, meldet main.bat, dass die Verarbeitung noch stattfindet. Wenn Sie im geöffneten Fenster von 1.bat oder 2.bat die Eingabetaste drücken, wird die temporäre Datei gelöscht und das Programm beendet. Dies simuliert das Stoppen der Verarbeitung für diese .bat-Datei. Wenn Sie dies sowohl für 1 als auch für 2.bat tun, meldet Ihnen main.bat, dass die Verarbeitung für diese Prozesse abgeschlossen ist. Sie können 1.bat und 2.bat dazu bringen, alles zu tun, was Sie wollen, solange Sie die temporäre Datei löschen, wenn Sie fertig sind. An diesem Punkt kann main.bat alles tun, was Sie wollen.

1. Fledermaus

echo %time% > 1.tmp
pause
del 1.tmp
exit 

2. Fledermaus

echo %time% > 2.tmp
pause
del 2.tmp
exit

main.bat

@echo off
start "1" 1.bat
start "2" 2.bat
    @ping -n 1 127.0.0.1 > nul
:loop
@echo Processing......
if not exist *.tmp goto :next
    @ping -n 5 127.0.0.1 > nul
goto loop
:next
@echo Done Processing!
RobW
quelle
Nachdem ich dies zuvor getan habe, kann ich Ihnen sagen, dass dieser Ansatz nicht so schwierig ist, wie es scheint. Darüber hinaus ist es einfach zu warten - Logik zu erweitern und hinzuzufügen und andere zu schulen, um sie zu warten. Normalerweise nehmen diese Dinge ihr eigenes Leben an ...
RobW
Ich bin mit dieser Lösung zufrieden.
user1068446
6

Einfach genug, vorausgesetzt, die Prozesse benötigen keine Standardeingabe oder -ausgabe. Über die Befehlszeile oder in einer Batchdatei:

process1 | process2 | process3 | process4

Dadurch werden alle vier Prozesse gleichzeitig ausgeführt und erst dann zurückgegeben, wenn alle beendet wurden. (Mögliche Ausnahme: Wenn ein Prozess die Standardausgabe explizit schließt, wird er möglicherweise so behandelt, als wäre er beendet worden. Aber das ist ungewöhnlich, nur sehr wenige Prozesse tun dies.)

Ich bin mir nicht sicher, wie viele Prozesse Sie auf diese Weise gleichzeitig starten können. Ich habe bis zu zehn ausprobiert.

Harry Johnston
quelle
Ähm, ich bekomme, dass alle Prozesse tatsächlich auf einmal gestartet werden, aber Prozess3 wartet, bis Prozess4 abgeschlossen ist, Prozess2 wartet, bis Prozess3 abgeschlossen ist, und so weiter. Dies ist übrigens von der klassischen Windows-Eingabeaufforderung.
Sergio
@Sergio: Was meinst du mit "weiter gewartet"?
Harry Johnston
1

Die einzige Möglichkeit, dies zu tun, besteht darin, separate Batchdateien (siehe start /?) zu starten , in denen die einzelne Aufgabe ausgeführt wird, und nach Abschluss eine Textdatei zu schreiben. Anschließend überprüfen Sie regelmäßig, ob die Textdateien erstellt wurden.

Tamara Wijsman
quelle
0

Sie können sich das Cmdlet Powershell Start-Job ansehen. Es sollte Ihnen erlauben, dies zu tun. Mehr hier Powershell ist die Shell von Microsoft. Es ist viel leistungsfähiger als Cmd-Skripte und belastet die Investition Ihrer Zeit

uSlackr
quelle
Dies wartet nicht darauf, dass alle von ihnen beendet werden?
Tamara Wijsman
Es kann sicherlich davon abhängen, wie Sie es schreiben. Sie können die gestarteten Jobs abfragen, um festzustellen, ob sie abgeschlossen sind, und Ihr Skript beenden, sobald sie abgeschlossen sind. Der Code auf dieser Seite verarbeitet eine ganze Liste von Jobs, jeweils drei, und wartet darauf, dass sie beendet werden.
uSlackr
Ähm, ich habe noch nie etwas mit Powershell gemacht. Ich habe versucht, das Beispiel zu ändern, um beliebige Prozesse auszuführen und auf deren Abschluss zu warten. Nach etwa 30 Minuten und 100 Suchvorgängen auf M $ technet habe ich aufgegeben. Es tut mir leid, wenn ich jemandes Gefühle verletzt habe, aber Powershell ist Mist. Es ist einfacher, dies in C zu tun (was ich denke ...). Trotzdem danke, ich wette, jemand wird dies immer noch nützlich finden.
Sergio
Wenn es eine Sache gibt, die Powershell nicht ist, dann ist es Mist und du wirst meine Gefühle nicht verletzen, wenn du sie nicht benutzt. Sie werden es jedoch nicht in 30 Minuten lernen.
uSlackr
1
PowerShell ist kein Mist, es ist nur eine vollständige Programmiersprache, die man lernen muss, anstelle einer traditionellen sh-ähnlichen Syntax. Ich erinnere mich, dass ich in Bezug auf Perl, Python, Tcl, C # und jede andere Sprache, die ich "für den Lulz" zu lernen versuchte, ohne wirklichen Gebrauch genau das gleiche Gefühl hatte. (Als ich sie tatsächlich brauchte , ging es ziemlich leicht.)
user1686
0

Oder Sie können dies verwenden: http://www.out-web.net/?p=167

Ich habe es getan, es funktioniert, aber es kommt manchmal vor, dass die PID des fertigen Prozesses sofort von einem anderen Windows-Prozess wiederverwendet wird, der gerade gestartet wurde, und es macht die Erkennung des Endes Ihres Prozesses gefährlich / fehlerhaft.

OlivierR
quelle
2
Bitte fassen Sie zusammen, was dieser Link sagt. Wenn die Seite ausfällt, ist diese Antwort nicht hilfreich.
Kevin Panko
Es scheint zu spät zu sein.
Robert Massa
0

Ich suchte auch nach einer ähnlichen Aufgabe. Ziel war es, mehrere Befehle parallel auszuführen und die Ausgabe (stdout & error) aller parallelen Prozesse zu extrahieren. Warten Sie dann, bis alle parallelen Prozesse abgeschlossen sind, und führen Sie einen weiteren Befehl aus. Es folgt ein Beispielcode für eine BAT-Datei, die in CMD ausgeführt werden kann:

( start "" /B cmd /c ping localhost -n 6 ^>nul timeout /t 5 /nobreak start "" /B /D "C:\users\username\Desktop" cmd /c dir ^> dr.txt ^2^>^&^1 start "" /B cmd /c ping localhost -n 11 ^>nul timeout /t 10 /nobreak ) | pause Echo waited timeout /t 12 /nobreak

Alle darin enthaltenen Anweisungen ()werden zuerst ausgeführt, warten Sie, bis sie abgeschlossen sind, und dann werden die letzten beiden Zeilen ausgeführt. Alle Befehle, die mit beginnen, startwerden gleichzeitig ausgeführt.

Diese Links sind hilfreich: /programming//a/43762349/9689416 und https://ss64.com/nt/start.html

Vivek
quelle