Uruchamianie wielu równoczesnych procesów w tle, a następnie poczekaj na zakończenie wszystkich procesów w systemie Windows

14

Czy ktoś wie, czy istnieje skrypt cmd, który to robi i / lub narzędzie wiersza polecenia jest gotowe do zadania?

Sergio
źródło
Może to spowodować uszkodzenie danych!
Santosh Kumar
8
@Santosh: co rozumiesz przez „może uszkodzić twoje dane”? W moim konkretnym przypadku zadania w tle przetwarzałyby własne niezależne zestawy danych. Brak ryzyka jednoczesnych modyfikacji.
Sergio
1
Po stronie API Win32, myślę, że WaitForMultipleObjects z bWaitAll = TRUE wykona zadanie. Nie byłoby trudno napisać program, który po prostu rozwidla programy podane w pliku wejściowym, jeśli nie ma satysfakcjonujących odpowiedzi.
user1686,
1
@grawity: tak, planuję to zrobić, jeśli nic się nie pojawi (i opublikuję kod tutaj), ale zobaczmy, czy uda mi się uniknąć wynalezienia koła :)
Sergio
Ponowne wynalezienie

Odpowiedzi:

10

Utwórz trzy pliki wsadowe poniżej. Main.bat uruchamia 1.bat i 2.bat

1.bat i 2.bat wypisują pliki tymczasowe, dla których sprawdza main.bat. Podczas gdy 1.bat i 2.bat działają, main.bat informuje, że przetwarzanie nadal występuje. Kiedy naciśniesz klawisz Enter w otwartym oknie 1.bat lub 2.bat, plik tymczasowy zostanie usunięty i program zostanie zamknięty. To symuluje zatrzymanie przetwarzania dla tego pliku .bat. Jeśli zrobisz to zarówno dla 1, jak i 2 bat, main.bat poinformuje cię, że przetwarzanie zostało zakończone dla tych procesów. Możesz zmusić 1.bat i 2.bat do zrobienia wszystkiego, co chcesz, pod warunkiem, że wyczyścisz plik tymczasowy po zakończeniu. W tym momencie main.bat może zrobić wszystko, co chcesz.

1. nietoperz

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

2. nietoperz

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
źródło
Po zrobieniu tego wcześniej mogę powiedzieć, że takie podejście nie jest tak trudne, jak się wydaje. Ponadto jest łatwy w utrzymaniu - aby rozwinąć i dodać logikę, a także łatwo wyszkolić kogoś innego w zakresie jej obsługi. Zwykle te rzeczy
zaczynają
Jestem zadowolony z tego rozwiązania.
user1068446,
Czy możesz rozwinąć polecenie @ping? Nie rozumiem, dlaczego zdecydujesz się to zrobić i czym jest 127.0.0.1.
Joe
6

To dość proste, pod warunkiem, że procesy nie wymagają standardowego wejścia lub wyjścia. Z wiersza polecenia lub w pliku wsadowym:

process1 | process2 | process3 | process4

Spowoduje to uruchomienie wszystkich czterech procesów jednocześnie i nie powróci, dopóki wszystkie się nie zakończą. (Możliwy wyjątek: jeśli proces jawnie zamyka standardowe wyjście, może być traktowany tak, jakby się zakończył. Ale to niezwykłe, bardzo niewiele procesów to robi.)

Nie jestem pewien, ile dokładnie procesów można uruchomić jednocześnie w ten sposób. Próbowałem do dziesięciu.

Harry Johnston
źródło
Uhm, otrzymuję to, że wszystkie procesy są rzeczywiście uruchamiane jednocześnie, ale proces3 czeka na zakończenie procesu 4, proces 2 czeka na zakończenie procesu 3 i tak dalej. Nawiasem mówiąc, pochodzi to z klasycznego wiersza poleceń systemu Windows.
Sergio
@Sergio: Co rozumiesz przez „ciągłe czekanie”?
Harry Johnston,
1

Jedynym sposobem na to jest uruchomienie osobnych plików wsadowych (patrz start /?), które uruchamiają indywidualne zadanie i zapisanie pliku tekstowego po zakończeniu. Następnie okresowo sprawdzasz, czy pliki tekstowe zostały utworzone.

Tamara Wijsman
źródło
0

Możesz spojrzeć na polecenie cmdlet Start-Job Powershell. Powinno to na to pozwolić. Więcej tutaj Powershell jest powłoką wyboru Microsoft. Jest znacznie potężniejszy niż skrypty cmd i zdecydowanie nie inwestuje twojego czasu

uSlackr
źródło
Nie czeka to na zakończenie wszystkich?
Tamara Wijsman
Z pewnością może to zależeć od tego, jak go napiszesz. Możesz sondować rozpoczęte zadania, aby sprawdzić, czy zostały one ukończone, i po zakończeniu zamknąć skrypt. Kod na tej stronie przetwarza całą listę zadań, po trzy na raz i czeka na zakończenie.
uSlackr
Nigdy nie robiłem nic z Powershellem. Próbowałem zmienić przykład, aby uruchomić dowolne procesy i zaczekać na ich zakończenie, a po około 30 minutach i 100 wyszukiwaniu w Mnet technet zrezygnowałem. Przepraszam, jeśli zraniłem czyjeś uczucia, ale Powershell to gówno. Łatwiej jest to zrobić w C (co, jak sądzę, mówi ...) Dzięki, założę się, że ktoś nadal uzna to za przydatne.
Sergio
Jeśli jest jedna rzecz, której Powershell nie jest gównem i nie skrzywdzisz moich uczuć, jeśli jej nie użyjesz. Jednak nie nauczysz się tego w ciągu 30 minut wyszukiwania.
uSlackr
1
PowerShell nie jest gównem, to po prostu pełny język programowania, którego trzeba się nauczyć, zamiast tradycyjnej składni podobnej do sh. Pamiętam, że czułem się dokładnie tak samo z Perlem, Pythonem, Tcl, C # i każdym innym językiem, którego próbowałem nauczyć się „dla lulz”, bez żadnego rzeczywistego zastosowania. (Kiedy jednak ich naprawdę potrzebowałem , poszło dość łatwo.)
user1686,
0

Lub możesz użyć tego: http://www.out-web.net/?p=167

Zrobiłem to, działa, jednak czasami zdarza się, że PID ukończonego procesu jest natychmiast ponownie wykorzystywany przez inny procesor Windows, który właśnie się rozpoczął, i sprawia, że ​​wykrycie końca twojego procesusa jest niebezpieczne / błędne.

OlivierR
źródło
2
Podsumuj, co mówi ten link. Jeśli strona się przewróci, ta odpowiedź nie będzie pomocna.
Kevin Panko
Wydaje się, że jest za późno.
Robert Massa,
0

Szukałem również podobnego zadania. Celem było uruchomienie wielu poleceń równolegle i wyodrębnienie danych wyjściowych (standardowe wyjście i błąd) wszystkich równoległych procesów. Następnie poczekaj na zakończenie wszystkich równoległych procesów i wykonaj inne polecenie. Poniżej znajduje się przykładowy kod pliku BAT, który można wykonać w CMD:

( 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

Wszystkie instrukcje wewnątrz ()są wykonywane najpierw, poczekaj na ich zakończenie, a następnie ostatnie dwa wiersze. Wszystkie polecenia startzaczynające się od są wykonywane jednocześnie.

Te linki są pomocne: /programming//a/43762349/9689416 i https://ss64.com/nt/start.html

Vivek Atal
źródło