Python 다중 프로세스, 다중 스레드 효율 비교
일반적으로 다중 스레드는 다중 프로세스에 비해 장점이 있다. 왜냐하면 하나의 프로세스를 만드는 비용이 비교적 크지만python에 GIL이라는 큰 자물쇠가 존재하기 때문에 계산 집약형 작업을 수행할 때 다중 스레드는 실제적으로 단일 스레드일 수밖에 없다.또한 스레드 사이의 전환 비용으로 인해 다중 스레드는 실제 단일 스레드보다 느리기 때문에python에서 계산 집약형 작업은 일반적으로 다중 프로세스를 사용합니다. 각 프로세스는 각자의 GIL이 있기 때문에 서로 간섭하지 않습니다.
그러나 IO 집약형 작업에서 CPU는 항상 대기 상태에 있고 운영체제는 외부 환경과 자주 상호작용을 해야 한다. 예를 들어 파일 읽기, 네트워크 간 통신 등이다.이 기간 동안 GIL이 방출되기 때문에 진정한 다중 스레드를 사용할 수 있다.
이상은 이론이다. 다음은 간단한 시뮬레이션 테스트를 한다. 대량의 계산용
math.sin() + math.cos()
으로 대체하고 IO 밀집형용time.sleep()
으로 시뮬레이션한다.Python에서는 여러 가지 방법으로 다중 프로세스와 다중 루틴을 실현할 수 있습니다. 여기서 효율 차이가 있는지 함께 살펴보겠습니다.
from multiprocessing import Pool
from threading import Thread
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time, os, math
from joblib import Parallel, delayed, parallel_backend
def f_IO(a): # IO
time.sleep(5)
def f_compute(a): #
for _ in range(int(1e7)):
math.sin(40) + math.cos(40)
return
def normal(sub_f):
for i in range(6):
sub_f(i)
return
def joblib_process(sub_f):
with parallel_backend("multiprocessing", n_jobs=6):
res = Parallel()(delayed(sub_f)(j) for j in range(6))
return
def joblib_thread(sub_f):
with parallel_backend('threading', n_jobs=6):
res = Parallel()(delayed(sub_f)(j) for j in range(6))
return
def mp(sub_f):
with Pool(processes=6) as p:
res = p.map(sub_f, list(range(6)))
return
def asy(sub_f):
with Pool(processes=6) as p:
result = []
for j in range(6):
a = p.apply_async(sub_f, args=(j,))
result.append(a)
res = [j.get() for j in result]
def thread(sub_f):
threads = []
for j in range(6):
t = Thread(target=sub_f, args=(j,))
threads.append(t)
t.start()
for t in threads:
t.join()
def thread_pool(sub_f):
with ThreadPoolExecutor(max_workers=6) as executor:
res = [executor.submit(sub_f, j) for j in range(6)]
def process_pool(sub_f):
with ProcessPoolExecutor(max_workers=6) as executor:
res = executor.map(sub_f, list(range(6)))
def showtime(f, sub_f, name):
start_time = time.time()
f(sub_f)
print("{} time: {:.4f}s".format(name, time.time() - start_time))
def main(sub_f):
showtime(normal, sub_f, "normal")
print()
print("------ ------")
showtime(joblib_process, sub_f, "joblib multiprocess")
showtime(mp, sub_f, "pool")
showtime(asy, sub_f, "async")
showtime(process_pool, sub_f, "process_pool")
print()
print("----- -----")
showtime(joblib_thread, sub_f, "joblib thread")
showtime(thread, sub_f, "thread")
showtime(thread_pool, sub_f, "thread_pool")
if __name__ == "__main__":
print("----- -----")
sub_f = f_compute
main(sub_f)
print()
print("----- IO -----")
sub_f = f_IO
main(sub_f)
결과:
----- -----
normal time: 15.1212s
------ ------
joblib multiprocess time: 8.2421s
pool time: 8.5439s
async time: 8.3229s
process_pool time: 8.1722s
----- -----
joblib thread time: 21.5191s
thread time: 21.3865s
thread_pool time: 22.5104s
----- IO -----
normal time: 30.0305s
------ ------
joblib multiprocess time: 5.0345s
pool time: 5.0188s
async time: 5.0256s
process_pool time: 5.0263s
----- -----
joblib thread time: 5.0142s
thread time: 5.0055s
thread_pool time: 5.0064s
위의 모든 방법은 6개의 프로세스/스레드를 통일적으로 만들었는데 그 결과 집약적 작업의 속도를 계산하는 것이다. 다중 프로세스 > 단일 프로세스/스레드 > 다중 스레드, IO 집약적 작업 속도: 다중 스레드 > 다중 프로세스 > 단일 프로세스/스레드이다.이상은Python 다중 프로세스, 다중 스레드 효율 비교의 상세한 내용입니다. 더 많은Python 다중 프로세스, 다중 스레드에 대한 자료는 저희 다른 관련 글을 주목해 주십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.