[PYTHON] 모든 스레드가 완료 될 때까지 파이썬 다중 스레드 대기
PYTHON모든 스레드가 완료 될 때까지 파이썬 다중 스레드 대기
이것은 비슷한 맥락에서 질문을 받았을 지 모르지만 약 20 분의 검색 후에 답을 찾을 수 없었기 때문에 물어볼 것입니다.
Python 스크립트 (scriptA.py라고 말하면 됨)와 스크립트 (scriptB.py라고 말하면 됨)를 작성했습니다.
scriptB에서 나는 scriptA를 여러 인자로 여러 번 호출하기를 원할 때마다 매 시간마다 실행하는데 약 1 시간이 걸린다. (거대한 스크립트는 많은 것을 처리한다. 걱정하지 마라.) 나는 그 스크립트를 실행할 수 있기를 원한다. scriptA는 동시에 모든 다른 인수를 가지고 있지만, 계속하기 전에 모든 것이 완료 될 때까지 기다려야합니다. 내 코드 :
import subprocess
#setup
do_setup()
#run scriptA
subprocess.call(scriptA + argumentsA)
subprocess.call(scriptA + argumentsB)
subprocess.call(scriptA + argumentsC)
#finish
do_finish()
같은 시간에 모든 subprocess.call ()을 실행하고 모두 완료 될 때까지 기다렸다가 어떻게해야합니까?
여기 예제와 같은 스레딩을 사용하려고했습니다.
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()
그러나 나는 이것이 옳다고 생각하지 않는다.
do_finish ()에 가기 전에 모두 실행이 끝났음을 어떻게 알 수 있습니까?
해결법
-
==============================
1.스크립트 끝에서 Thread 객체의 join 메소드를 사용해야한다.
스크립트 끝에서 Thread 객체의 join 메소드를 사용해야한다.
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() t1.join() t2.join() t3.join()
따라서 주 스레드는 t1, t2 및 t3이 끝날 때까지 대기합니다.
-
==============================
2.스레드를 목록에 넣고 Join 메서드를 사용하십시오.
스레드를 목록에 넣고 Join 메서드를 사용하십시오.
threads = [] t = Thread(...) threads.append(t) ...repeat as often as necessary... # Start all threads for x in threads: x.start() # Wait for all of them to finish for x in threads: x.join()
-
==============================
3.입력 목록을 기반으로하는 목록 이해력을 선호합니다.
입력 목록을 기반으로하는 목록 이해력을 선호합니다.
inputs = [scriptA + argumentsA, scriptA + argumentsB, ...] threads = [Thread(target=call_script, args=(i)) for i in inputs] [t.start() for t in threads] [t.join() for t in threads]
-
==============================
4.파이썬 3에서는 파이썬 3.2부터 동일한 결과에 도달하기위한 새로운 접근법이 있습니다. 개인적으로 전통적인 스레드 생성 / 시작 / 결합, concurrent.futures 패키지를 선호합니다 : https://docs.python.org/3/library/ concurrent.futures.html
파이썬 3에서는 파이썬 3.2부터 동일한 결과에 도달하기위한 새로운 접근법이 있습니다. 개인적으로 전통적인 스레드 생성 / 시작 / 결합, concurrent.futures 패키지를 선호합니다 : https://docs.python.org/3/library/ concurrent.futures.html
ThreadPoolExecutor를 사용하면 코드는 다음과 같습니다.
from concurrent.futures.thread import ThreadPoolExecutor def call_script(arg) subprocess.call(scriptA + arg) args = [argumentsA, argumentsB, argumentsC] with ThreadPoolExecutor(max_workers=2) as executor: for arg in args: executor.submit(call_script, arg) print('All tasks has been finished')
장점 중 하나는 최대 동시 작업자 수를 설정하는 처리량을 제어 할 수 있다는 것입니다.
-
==============================
5.아래 열거 된 것과 같은 클래스를 사용하여 병렬 함수로 실행할 함수 또는 console_script를 추가하고 실행을 시작한 다음 모든 작업이 완료 될 때까지 기다릴 수 있습니다.
아래 열거 된 것과 같은 클래스를 사용하여 병렬 함수로 실행할 함수 또는 console_script를 추가하고 실행을 시작한 다음 모든 작업이 완료 될 때까지 기다릴 수 있습니다.
from multiprocessing import Process class ProcessParallel(object): """ To Process the functions parallely """ def __init__(self, *jobs): """ """ self.jobs = jobs self.processes = [] def fork_processes(self): """ Creates the process objects for given function deligates """ for job in self.jobs: proc = Process(target=job) self.processes.append(proc) def start_all(self): """ Starts the functions process all together. """ for proc in self.processes: proc.start() def join_all(self): """ Waits untill all the functions executed. """ for proc in self.processes: proc.join() def two_sum(a=2, b=2): return a + b def multiply(a=2, b=2): return a * b #How to run: if __name__ == '__main__': #note: two_sum, multiply can be replace with any python console scripts which #you wanted to run parallel.. procs = ProcessParallel(two_sum, multiply) #Add all the process in list procs.fork_processes() #starts process execution procs.start_all() #wait until all the process got executed procs.join_all()
-
==============================
6.어쩌면, 뭔가
어쩌면, 뭔가
for t in threading.enumerate(): if t.daemon: t.join()
-
==============================
7.난 그냥 for 루프를 사용하여 만든 모든 스레드를 기다릴 필요가 같은 문제가 왔어. 난 그냥 다음 코드 조각을 시도했다. 그것은 완벽한 솔루션이되지 않을 수도 있지만 간단한 해결책이 될 것이라고 생각 테스트하기 :
난 그냥 for 루프를 사용하여 만든 모든 스레드를 기다릴 필요가 같은 문제가 왔어. 난 그냥 다음 코드 조각을 시도했다. 그것은 완벽한 솔루션이되지 않을 수도 있지만 간단한 해결책이 될 것이라고 생각 테스트하기 :
for t in threading.enumerate(): try: t.join() except RuntimeError as err: if 'cannot join current thread' in err: continue else: raise
-
==============================
8.스레딩 모듈 문서에서
스레딩 모듈 문서에서
따라서 작성한 스레드 목록을 유지하는 데 관심이없는 경우 두 가지 경우를 포착하십시오.
import threading as thrd def alter_data(data, index): data[index] *= 2 data = [0, 2, 6, 20] for i, value in enumerate(data): thrd.Thread(target=alter_data, args=[data, i]).start() for thread in thrd.enumerate(): if thread.daemon: continue try: thread.join() except RuntimeError as err: if 'cannot join current thread' in err.args[0]: # catchs main thread continue else: raise
그래서:
>>> print(data) [0, 4, 12, 40]
from https://stackoverflow.com/questions/11968689/python-multithreading-wait-till-all-threads-finished by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 파이썬 사전을 XML로 직렬화 [닫힘] (0) | 2018.10.04 |
---|---|
[PYTHON] 안에있는 문자열을 올바르게 정렬하는 방법? [복제] (0) | 2018.10.04 |
[PYTHON] 파이썬 CSV 오류 : 라인에 NULL 바이트가 들어 있습니다. (0) | 2018.10.04 |
[PYTHON] 두 목록 사이의 조합? (0) | 2018.10.04 |
[PYTHON] NameError를주는 모듈을 다시로드하고 있습니다 : 'reload'이름이 정의되지 않았습니다. (0) | 2018.10.04 |