Chcę przetwarzać wiele plików, a ponieważ mam tutaj kilka rdzeni, chcę to zrobić równolegle:
for i in *.myfiles; do do_something $i `derived_params $i` other_params; done
Znam rozwiązanie Makefile , ale moje polecenia wymagają argumentów z listy globowania powłoki. Znalazłem:
> function pwait() {
> while [ $(jobs -p | wc -l) -ge $1 ]; do
> sleep 1
> done
> }
>
Aby go użyć, wystarczy umieścić & po zadaniach i wywołanie oczekujące, parametr podaje liczbę równoległych procesów:
> for i in *; do
> do_something $i &
> pwait 10
> done
Ale to nie działa zbyt dobrze, np. Próbowałem z np. Konwersją wielu plików w pętli for, ale dałem mi błąd i pozostawiłem zadania cofnięte.
Nie mogę uwierzyć, że nie zostało to jeszcze zrobione, ponieważ dyskusja na liście mailingowej zsh jest już tak stara. Czy znasz coś lepszego?
bash
shell
zsh
parallel-processing
matematyka
źródło
źródło
echo "DONE"
po pętli, która została wykonana, zanim aktywne zadania nie zostały zakończone. => To sprawiło, że pomyślałem, że prace nie zostały wykonane.Odpowiedzi:
Makefile to dobre rozwiązanie twojego problemu. Możesz zaprogramować to równoległe wykonywanie w powłoce, ale jest to trudne, jak zauważyłeś. Równoległa implementacja marki nie tylko zajmie się uruchamianiem zadań i wykrywaniem ich zakończenia, ale także obsługi równoważenia obciążenia, co jest trudne.
Wymóg globowania nie jest przeszkodą: istnieją implementacje, które go obsługują. Marka GNU, która ma rozszerzenie symboli wieloznacznych, takie jak
$(wildcard *.c)
dostęp do powłoki, np.$(shell mycommand)
(Funkcje wyszukiwania w GNU tworzą instrukcję, aby uzyskać więcej informacji). Jest to ustawienie domyślnemake
w systemie Linux i dostępne w większości innych systemów. Oto szkielet Makefile, który możesz dostosować do swoich potrzeb:Uruchom coś
make -j4
w stylu równoległego wykonywania czterech zadań lubmake -j -l3
utrzymaj średnie obciążenie około 3.źródło
Nie jestem pewien, jakie są twoje pochodne argumenty. Ale z GNU Parallel http: // www.gnu.org/software/parallel/ możesz to zrobić, aby uruchomić jedno zadanie na rdzeń procesora:
Jeśli chcesz uzyskać po prostu zmianę .extension, {.} Może się przydać:
Obejrzyj wideo wprowadzające do GNU Parallel na http://www.youtube.com/watch?v=OpaiGYxkSuQ
źródło
Czy użycie polecenia powłoki nie
wait
działałoby dla Ciebie?Pętla wykonuje zadanie, czeka na niego, a następnie wykonuje następne zadanie. Jeśli powyższe nie działa dla Ciebie, twoje może działać lepiej, jeśli się
pwait
później przejdzieszdone
.źródło
for
pętli, aby ograniczyć to:for file in *; do for i in {1..10}; do do_something "$i" & done; wait; done
(niesprawdzone) To powinno zrobić dziesięć na raz i poczekać, aż wszystkie dziesięć z każdej grupy zostanie zakończone przed rozpoczęciem następnej dziesięciu. Twoja pętla wykonuje&
dyskusję pojedynczo . Zobacz pytanie, do którego JRobert podłączył inne opcje. Wyszukaj w przepełnieniu stosu inne pytania podobne do twojego (i tego).for i in *
. Musi przekazać argumenty do pętli za pomocą potoku lub czegoś takiego. Następnie zamiast wewnętrznej pętli można uruchomić licznik przyrostowy i uruchomić"micro-"wait"-s"
co „$ ((i% 32))” -eq '0'wait
z wewnętrzną pętlą licznika działało dla mnie dobrze. Dzięki!Dlaczego nikt jeszcze nie wspomniał o Xargs?
Zakładając, że masz dokładnie trzy argumenty,
W przeciwnym razie użyj ogranicznika (przydatne jest do tego null):
EDYCJA: w powyższym przypadku każdy parametr powinien być oddzielony znakiem null, a następnie liczbę parametrów należy określić za pomocą xargs -n.
źródło
Próbowałem niektórych odpowiedzi. Sprawiają, że skrypt jest nieco bardziej skomplikowany niż jest to potrzebne. Najlepiej byłoby użyć
parallel
lubxargs
byłoby lepiej, jednak jeśli operacje wewnątrz pętli for są skomplikowane, może być problematyczne utworzenie dużych i długich plików linii, które będą dostarczane równolegle. zamiast tego możemy użyć źródła w następujący sposóbTak wyglądałoby rozwiązanie problemu
zdefiniuj zrób coś jako
do_something.sh
}
wykonać za pomocą
xarg
lubgnu parallel
Zakładam, że implikowana jest funkcjonalna niezależność iteracji for.
źródło