Mogłem o to zapytać w podobnym kontekście, ale nie mogłem znaleźć odpowiedzi po około 20 minutach poszukiwań, więc zapytam.
Napisałem skrypt w Pythonie (powiedzmy: scriptA.py) i skrypt (powiedzmy scriptB.py)
W skrypcie B chcę wywołać skryptA wiele razy z różnymi argumentami, za każdym razem uruchomienie trwa około godziny (jest to ogromny skrypt, robi wiele rzeczy ... nie martw się o to) i chcę mieć możliwość uruchomienia scriptA ze wszystkimi różnymi argumentami jednocześnie, ale przed kontynuowaniem muszę poczekać, aż WSZYSTKIE zostaną wykonane; mój kod:
import subprocess
#setup
do_setup()
#run scriptA
subprocess.call(scriptA + argumentsA)
subprocess.call(scriptA + argumentsB)
subprocess.call(scriptA + argumentsC)
#finish
do_finish()
Chcę uruchomić wszystko subprocess.call()
w tym samym czasie, a następnie poczekać, aż wszystkie skończą , jak mam to zrobić?
Próbowałem użyć wątków, jak na przykładzie tutaj :
from threading import Thread
import subprocess
def call_script(args)
subprocess.call(args)
#run scriptA
t1 = Thread(target=call_script, args=(scriptA + argumentsA))
t2 = Thread(target=call_script, args=(scriptA + argumentsB))
t3 = Thread(target=call_script, args=(scriptA + argumentsC))
t1.start()
t2.start()
t3.start()
Ale nie sądzę, żeby to było słuszne.
Skąd mam wiedzieć, że wszyscy skończyli biegać przed pójściem do mojego do_finish()
?
źródło
join
bloków do momentu zakończenia wykonywania wątku. I tak będziesz musiał poczekać na wszystkie wątki. Jeślit1
skończysz jako pierwszy, zaczniesz czekaćt2
(co może być już zakończone i natychmiast zaczniesz czekaćt3
). Jeśli wykonaniet1
zajęło najwięcej czasu, po powrocie z niego obat1
it2
powrócą natychmiast bez blokowania.join
pewnym sensie dołącza bieżący proces do wątku i czeka, aż się skończy, a jeśli t2 zakończy się przed t1, to po zakończeniu t1 sprawdzi, czy t2 jest zakończony. że tak jest, a następnie sprawdź t3..etc..etc .. i tylko wtedy, gdy wszystko jest zrobione, będzie kontynuowane. niesamowite.Umieść wątki na liście, a następnie użyj metody Join
źródło
for x in threads: x.join()
a nie używałbym ComprehantionW Pythonie3, od Pythona 3.2, jest nowe podejście do osiągnięcia tego samego wyniku, który osobiście wolę od tradycyjnego tworzenia wątku / start / dołączanie, pakiet
concurrent.futures
: https://docs.python.org/3/library/concurrent.futures .htmlUżycie
ThreadPoolExecutor
kodu wyglądałoby tak:Wynik poprzedniego kodu jest podobny do:
Jedną z zalet jest to, że można kontrolować przepływność, ustawiając maksymalną liczbę równoczesnych pracowników.
źródło
with
instrukcji jest wykonywany po zakończeniu wszystkich zadań.with
działa instrukcja w tym przypadku. W każdym razie, zawsze możesz otworzyć nowe pytanie w SO i wysłać swój kod, abyśmy mogli Ci pomóc dowiedzieć się, co się dzieje w Twojej sprawie.concurrent.futures.wait
funkcji, prawdziwy przykład możesz zobaczyć tutaj Oficjalna dokumentacja: docs.python.org/3/library/ ...Preferuję rozumienie list na podstawie listy wejściowej:
źródło
for t in threads:t.start()
czy nie jest lepiej?Możesz mieć klasę podobną do poniżej, z której możesz dodać 'n' liczbę funkcji lub skryptów console_scripts, które chcesz wykonać równolegle, i rozpocząć wykonywanie i poczekać na zakończenie wszystkich zadań.
źródło
Z
threading
dokumentacji modułuTak więc, aby uchwycić te dwa przypadki, gdy nie jesteś zainteresowany utrzymywaniem listy utworzonych wątków:
Po czym:
źródło
Może coś takiego
źródło
Właśnie natknąłem się na ten sam problem, w którym musiałem poczekać na wszystkie wątki, które zostały utworzone za pomocą pętli for. Właśnie wypróbowałem następujący fragment kodu Może nie jest to idealne rozwiązanie, ale pomyślałem, że będzie to proste rozwiązanie testować:
źródło