파이썬 멀티스레드는 모든 스레드가 완료될 때까지 기다립니다.
비슷한 맥락에서 물어본 것일 수도 있지만 20분 정도 검색해보니 답을 찾지 못해서 물어보겠습니다.
저는 파이썬 스크립트(예: scriptA.py )와 스크립트(예: B 스크립트)를 작성했습니다.파이)
스크립트 B에서 저는 다른 인수로 스크립트 A를 여러 번 호출하고 싶습니다. 매번 실행하는 데 약 한 시간이 걸립니다. (커다란 스크립트로 많은 일을 합니다.)걱정하지 마세요) 그리고 저는 스크립트 A를 모든 다른 인수와 동시에 실행할 수 있기를 원하지만, 계속하기 전에 모든 인수가 완료될 때까지 기다려야 합니다. 제 코드:
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()
?
스레드를 목록에 넣은 다음 가입 방법 사용
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()
의 가입 방법을 사용해야 합니다.Thread
개체입니다.
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
집행을 마치다
Python3에서는 Python3.2 이후 동일한 결과에 도달하기 위한 새로운 접근 방식이 있습니다. 저는 개인적으로 전통적인 스레드 생성/시작/가입, 패키지보다 선호합니다.concurrent.futures
: https://docs.python.org/3/library/concurrent.futures.html
사용ThreadPoolExecutor
코드는 다음과 같습니다.
from concurrent.futures.thread import ThreadPoolExecutor
import time
def call_script(ordinal, arg):
print('Thread', ordinal, 'argument:', arg)
time.sleep(2)
print('Thread', ordinal, 'Finished')
args = ['argumentsA', 'argumentsB', 'argumentsC']
with ThreadPoolExecutor(max_workers=2) as executor:
ordinal = 1
for arg in args:
executor.submit(call_script, ordinal, arg)
ordinal += 1
print('All tasks has been finished')
이전 코드의 출력은 다음과 같습니다.
Thread 1 argument: argumentsA
Thread 2 argument: argumentsB
Thread 1 Finished
Thread 2 Finished
Thread 3 argument: argumentsC
Thread 3 Finished
All tasks has been finished
장점 중 하나는 최대 동시 작업자를 설정하는 처리량을 제어할 수 있다는 것입니다.
대신 다중 처리를 사용하려면 프로세스 풀 실행기를 사용할 수 있습니다.
저는 입력 목록을 기반으로 한 목록 이해를 사용하는 것을 선호합니다.
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]
아래와 같은 클래스에서 병렬로 실행할 'n'개의 함수 또는 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()
방금 for 루프를 사용하여 생성된 모든 스레드를 기다려야 하는 동일한 문제를 발견했습니다.저는 방금 다음 코드를 사용해 보았습니다.완벽한 솔루션은 아닐 수도 있지만 테스트를 위한 간단한 솔루션이라고 생각했습니다.
for t in threading.enumerate():
try:
t.join()
except RuntimeError as err:
if 'cannot join current thread' in err:
continue
else:
raise
메인 스레드 개체가 있습니다. 이것은 파이썬 프로그램의 초기 제어 스레드에 해당합니다.데몬 스레드가 아닙니다.
더미 스레드 개체가 생성될 수 있습니다.이것들은 "외계 스레드"에 해당하는 스레드 객체이며, C 코드에서 직접처럼 스레드 모듈 외부에서 시작된 제어 스레드입니다.더미 스레드 객체는 제한된 기능을 가지고 있으며, 항상 활성 및 대모닉으로 간주되며, 다음과 같을 수 없습니다.
join()
스레드의 에 절대. 외계 스레드의 종료를 탐지하는 것이 불가능하기 때문에 삭제되지 않습니다.
따라서 생성한 스레드 목록을 유지하는 데 관심이 없는 경우 이 두 가지 경우를 파악하려면 다음과 같이 하십시오.
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]
아마도, 비슷한 것.
for t in threading.enumerate():
if t.daemon:
t.join()
join만 사용하면 스레드와 잘못된 긍정적 상호 작용이 발생할 수 있습니다.문서에 언급된 바와 같이:
시간 초과 인수가 있고 없음이 아닌 경우에는 작업의 시간 초과(초 또는 그 부분)를 지정하는 부동 소수점 번호여야 합니다.join()은 항상 None을 반환하므로 join() 후 isAlive()를 호출하여 시간 초과가 발생했는지 여부를 결정해야 합니다. 스레드가 아직 활성 상태이면 join() 호출이 시간 초과되었습니다.
및 예시적인 코드 조각:
threads = []
for name in some_data:
new = threading.Thread(
target=self.some_func,
args=(name,)
)
threads.append(new)
new.start()
over_threads = iter(threads)
curr_th = next(over_threads)
while True:
curr_th.join()
if curr_th.is_alive():
continue
try:
curr_th = next(over_threads)
except StopIteration:
break
언급URL : https://stackoverflow.com/questions/11968689/python-multithreading-wait-till-all-threads-finished
'source' 카테고리의 다른 글
엔티티 매핑에서 시퀀스의 증분 크기는 [50]으로 설정되고 연결된 데이터베이스 시퀀스 증분 크기는 [1]입니다. (0) | 2023.07.15 |
---|---|
요소가 배열에 있는지 확인하는 방법 (0) | 2023.07.15 |
com.google.android.gms.common.api에 로그인하지 못했습니다.API 예외: 10: (0) | 2023.07.15 |
R에서 실행을 일시 중지하고, 자고, X초 동안 기다리도록 하는 방법은 무엇입니까? (0) | 2023.07.15 |
Spring camel 케이스 속성을 대문자 환경 변수로 설정하는 방법은 무엇입니까? (0) | 2023.07.15 |