Próbuję napisać plik .sh, który uruchamia wiele programów jednocześnie
Próbowałem tego
prog1
prog2
Ale to uruchamia program prog1, następnie czeka do zakończenia programu prog1, a następnie rozpoczyna program prog2 ...
Jak mogę je uruchomić równolegle?
bash
parallel-processing
Betamoo
źródło
źródło
wait
! Tak, w bash możesz poczekać na procesy potomne skryptu.nohup
aby zapobiec zabiciu programu podczas rozłączania się powłoki.Co powiesz na:
Spowoduje to:
prog1
.prog2
i trzymaj go na pierwszym planie , abyś mógł go zamknąćctrl-c
.prog2
, można powrócić doprog1
„s planie , dzięki czemu można również zamknąć go zctrl-c
.źródło
prog1
, gdyprog2
zakończone jest? Pomyśl onode srv.js & cucumberjs
prog1 & prog2 ; fg
służyła do uruchamiania wielu tuneli ssh jednocześnie. Mam nadzieję, że to komuś pomoże.prog2
nie uruchomi się natychmiast, wrócisz do posiadaniaprog1
na pierwszym planie. Jeśli jest to pożądane, to jest w porządku.prog1 & prog2 && kill $!
.Możesz użyć
wait
:Przypisuje PID programu w tle do zmiennych (
$!
jest to PID ostatniego uruchomionego procesu), a następniewait
polecenie czeka na nie. To miłe, ponieważ jeśli zabijesz skrypt, to również zabije procesy!źródło
#!/usr/bin/env bash ARRAY='cat bat rat' for ARR in $ARRAY do ./run_script1 $ARR & done P1=$! wait $P1 echo "INFO: Execution of all background processes in the for loop has completed.."
${}
aby interpolować go do listy ciągów lub podobnej.Z GNU Parallel http://www.gnu.org/software/parallel/ jest to tak proste, jak:
Lub jeśli wolisz:
Ucz się więcej:
źródło
parallel
o różnej składni. Na przykład w pochodnych Debianamoreutils
pakiet zawiera inną komendę o nazwie,parallel
która zachowuje się zupełnie inaczej.parallel
lepsze niż używanie&
?parallel
jest lepszy, gdy jest więcej zadań niż rdzeni, w którym to przypadku&
można uruchomić więcej niż jedno zadanie na rdzeń jednocześnie. (por. zasada szuflady )Jeśli chcesz mieć możliwość łatwego uruchamiania i zabijania wielu procesów
ctrl-c
, jest to moja ulubiona metoda: spawnuj wiele procesów w tle w(…)
podpowłoce i pułapkęSIGINT
do wykonaniakill 0
, która zabije wszystko odrodzone w grupie podpowłoki:Możesz mieć złożone struktury wykonawcze procesów, a wszystko zamknie się za pomocą jednego
ctrl-c
(upewnij się, że ostatni proces jest uruchomiony na pierwszym planie, tzn. Nie dołączaj&
po nimprog1.3
):źródło
xargs -P <n>
pozwala na uruchamianie<n>
poleceń równolegle.Chociaż
-P
jest to niestandardowa opcja, zarówno implementacje GNU (Linux), jak i macOS / BSD ją obsługują.Poniższy przykład:
Dane wyjściowe wyglądają mniej więcej tak:
Czas pokazuje, że polecenia były uruchamiane równolegle (ostatnie polecenie zostało uruchomione dopiero po zakończeniu pierwszego z 3 oryginalnych, ale wykonane bardzo szybko).
Samo
xargs
polecenie nie powróci, dopóki wszystkie polecenia nie zostaną zakończone, ale można je wykonać w tle, kończąc je operatorem sterowania,&
a następnie używającwait
wbudowanego programu, aby czekać na zakończenie całegoxargs
polecenia.Uwaga:
BSD / MacOS
xargs
wymaga, aby określić liczbę poleceń uruchomić równolegle wyraźnie , natomiast GNUxargs
pozwala określić-P 0
uruchomić jak najwięcej jak to możliwe równolegle.Dane wyjściowe z procesów przebiegających równolegle docierają w miarę ich generowania , więc będą nieprzewidywalnie przeplatane .
parallel
, jak wspomniano w odpowiedzi Ole ( nie jest standardem w większości platform), wygodnie serializuje (grupuje) dane wyjściowe dla poszczególnych procesów i oferuje wiele bardziej zaawansowanych funkcji.źródło
Błędy przekierowujące do oddzielnych dzienników.
źródło
prog1 2> .errorprog1.log & prog2 2> .errorprog2.log &
ls notthere1 & 2> .errorprog1.log; ls notthere2 & 2>.errorprog2.log
. Błędy trafiają do konsoli, a oba pliki błędów są puste. Jak mówi @Dennis Williamson,&
jest separatorem,;
więc (a) musi przejść na końcu polecenia (po każdym przekierowaniu) i (b) wcale nie potrzebujesz;
:-)Istnieje bardzo przydatny program, który wywołuje nohup.
źródło
nohup
sam w sobie nie uruchamia niczego w tle, a używanienohup
nie jest wymaganiem ani warunkiem wstępnym do uruchamiania zadań w tle. Często są one przydatne razem, ale jako takie nie odpowiadają na pytanie.Oto funkcja, której używam, aby uruchomić równolegle maksymalnie n procesu (n = 4 w przykładzie):
Jeśli parametr max_children jest ustawiony na liczbę rdzeni, funkcja ta spróbuje uniknąć wolnych rdzeni.
źródło
wait -n
wymaga wersjibash
4.3+ i zmienia logikę na oczekiwanie na zakończenie dowolnego z podanych / domyślnych procesów.Możesz spróbować ppss . ppss jest dość potężny - możesz nawet stworzyć mini-klaster. xargs -P może być również przydatny, jeśli masz do czynienia z kłopotliwie równoległym przetwarzaniem.
źródło
Ostatnio miałem podobną sytuację, w której musiałem uruchamiać wiele programów jednocześnie, przekierowywać ich wyniki do oddzielnych plików dziennika i czekać na ich zakończenie, a skończyło się na czymś takim:
Źródło: http://joaoperibeiro.com/execute-multiple-programs-and-redirect-their-outputs-linux/
źródło
Process Spawning Manager
Jasne, technicznie rzecz biorąc, są to procesy, a ten program powinien naprawdę nazywać się menedżerem spawnowania procesów, ale dzieje się tak tylko ze względu na sposób, w jaki BASH działa, gdy rozwidla się za pomocą ampersand, używa wywołania systemowego fork () lub clone () który klonuje do oddzielnej przestrzeni pamięci zamiast czegoś takiego jak pthread_create (), który współdzieli pamięć. Gdyby BASH wspierał to drugie, każda „sekwencja wykonania” działałaby tak samo i mogłaby być nazwana tradycyjnym wątkiem, zyskując bardziej wydajny ślad pamięci. Funkcjonalnie jednak działa tak samo, choć nieco trudniej, ponieważ zmienne GLOBALNE nie są dostępne w każdym klonie roboczym, stąd użycie pliku komunikacji międzyprocesowej i podstawowego semafora stad do zarządzania krytycznymi sekcjami. Rozwidlenie od BASH jest oczywiście podstawową odpowiedzią tutaj, ale czuję się tak, jakby ludzie to wiedzieli, ale naprawdę chcą zarządzać tym, co się pojawiło, zamiast tylko rozwidlać je i zapomnieć. Pokazuje to sposób zarządzania nawet 200 wystąpieniami rozwidlonych procesów, z których wszystkie uzyskują dostęp do jednego zasobu. Najwyraźniej to przesada, ale podobało mi się pisanie, więc kontynuowałem. Zwiększ odpowiednio rozmiar swojego terminala. Mam nadzieję, że uznasz to za przydatne.
źródło
Twój skrypt powinien wyglądać następująco:
Zakładając, że twój system może przyjmować n zadań jednocześnie. użyj funkcji wait, aby uruchomić tylko n zadań jednocześnie.
źródło
Dzięki bashj ( https://sourceforge.net/projects/bashj/ ) powinieneś być w stanie uruchomić nie tylko wiele procesów (tak jak sugerowali inni), ale także wiele wątków w jednym JVM kontrolowanym ze skryptu. Ale oczywiście wymaga to JDK Javy. Wątki zużywają mniej zasobów niż procesy.
Oto działający kod:
źródło