이 기사는 Python 동시성 PoolExecutor(예제 포함)에 대한 소개를 제공합니다. 이는 특정 참조 가치가 있습니다. 도움이 필요한 친구가 도움이 되기를 바랍니다.
멀티스레딩 및 멀티프로세싱을 사용하여 일반 동시성 요구사항을 완료합니다. 시작 중에 시작 및 조인과 같은 단계를 생략할 수 없습니다. 복잡한 요구사항의 경우 1~2개의 대기열이 필요합니다.
요구사항이 점점 더 복잡해지면서 좋은 디자인과 기능 수준 추상화가 없으면 코드가 많아질수록 디버깅이 더 어려워집니다.
동시 실행이 필요하지만 실시간 요구 사항이 높지 않은 작업의 경우 Concurrent.futures 패키지의 PoolExecutor 클래스를 사용하여 구현할 수 있습니다.
이 패키지는 스레드 풀 실행기 ThreadPoolExecutor와 프로세스 풀 실행기 ProcessPoolExecutor라는 두 가지 실행기를 제공합니다. 두 실행기는 동일한 API를 제공합니다.
풀 개념의 주요 목적은 재사용을 위한 것입니다. 즉, 스레드나 프로세스를 수명 주기 동안 여러 번 사용할 수 있도록 하는 것입니다. 스레드 및 프로세스 생성에 따른 오버헤드를 줄이고 프로그램 성능을 향상시킵니다. 재사용은 필수 규칙은 아니지만 프로그래머가 애플리케이션에서 풀을 사용하는 주된 이유입니다.
풀에는 max_workers에 의해 지정된 고정된 개수의 스레드/프로세스만 있습니다.
작업은 executor.submit을 통해 실행자의 작업 대기열에 제출되고 미래 개체가 반환됩니다.
Future는 일반적인 동시성 디자인 패턴입니다.
미래 객체는 아직 준비되지 않은(완료된) 일부 결과를 나타냅니다. 이 결과는 "미래"의 특정 시간에 준비된 후에 얻을 수 있습니다.
과제는 다양한 작업자들 사이에서 수행될 예정입니다.
하지만 일단 작업이 실행되면 실행이 완료될 때까지 작업자가 점유된다는 점에 유의하세요! 작업자가 충분하지 않으면 다른 작업이 계속 대기하게 됩니다! 따라서 PoolExecutor는 실시간 작업에 적합하지 않습니다.
import concurrent.futures import time from itertools import count number_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] def evaluate_item(x): for i in count(x): # count 是无限迭代器,会一直递增。 print(f"{x} - {i}") time.sleep(0.01) if __name__ == "__main__": # 进程池 start_time_2 = time.time() # 使用 with 在离开此代码块时,自动调用 executor.shutdown(wait=true) 释放 executor 资源 with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: # 将 10 个任务提交给 executor,并收集 futures futures = [executor.submit(evaluate_item, item) for item in number_list] # as_completed 方法等待 futures 中的 future 完成 # 一旦某个 future 完成,as_completed 就立即返回该 future # 这个方法,使每次返回的 future,总是最先完成的 future # 而不是先等待任务 1,再等待任务 2... for future in concurrent.futures.as_completed(futures): print(future.result()) print ("Thread pool execution in " + str(time.time() - start_time_2), "seconds")
위 코드에서 항목 1 2 3 4 5가 포함된 5개 작업은 항상 모든 작업자를 차지하지만 5개 작업 6 7 8 9 10은 영원히 대기합니다! ! !
API 세부 설명
concurrent.futures에는 API의 세 부분이 포함되어 있습니다.
PoolExecutor: 두 실행자의 API입니다.
Constructor: 주요 매개변수는 스레드 풀 크기(또는 작업자)를 지정하는 데 사용되는 max_workers입니다. number)
submit(fn, *args, **kwargs): 작업 함수 fn을 실행자에게 제출합니다. args 및 kwargs는 fn에 필요한 매개변수입니다.
결과를 얻기 위해 미래를 반환합니다
map(func, *iterables, timeout=None, Chunksize=1): 작업은 동일하지만 매개변수만 다른 경우 제출 대신 이 방법을 사용할 수 있습니다. iterables의 각 요소는 func의 매개변수 집합에 해당합니다.
futures의 반복자를 반환합니다
shutdown(wait=True): 실행기를 종료합니다. 일반적으로 with 관리자를 사용하여 자동으로 종료합니다.
Future: 작업이 실행자에게 제출된 후 future가 반환됩니다.
future.result(timout=None): 가장 일반적으로 사용되는 메서드는 작업 결과를 반환합니다. 작업이 아직 종료되지 않은 경우 이 메서드는 영원히 기다립니다!
timeout은 시간 초과를 지정하며 None인 경우 시간 초과 제한이 없습니다.
Exception(timeout=None): 작업에서 발생한 예외를 제공합니다. result()와 마찬가지로 작업이 끝날 때까지 기다립니다.
cancel(): 이 작업 취소
add_done_callback(fn): future가 완료된 후 fn(future)이 실행됩니다.
running(): 실행 중인지 여부
done(): 미래가 끝났는지 여부, boolean
... 자세한 내용은 공식 문서를 참조하세요
모듈에 포함된 유틸리티 함수
concurrent.futures.as_completed (fs, timeout =None): fs(futures iterable)의 future가 완료될 때까지 기다립니다.
fs의 future가 완료되면 이 함수는 즉시 future를 반환합니다.
이 방법을 사용하면 매번 반환된 미래가 항상 가장 먼저 완료됩니다. 먼저 작업 1을 기다린 다음 작업 2를 기다리는 대신...
보통 as_completed(fs)에서 미래를 위해 이 함수를 사용하세요.
concurrent.futures.wait(fs, timeout=None, return_when=ALL_COMPLETED): return_when에 의해 지정된 이벤트가 발생할 때까지 기다리거나 시간 초과
return_when에는 세 가지 옵션이 있습니다: ALL_COMPLETED(fs의 모든 future가 완료됨), FIRST__COMPLETED(Any fs의 future가 완료됨) 및 FIRST_EXCEPTION(작업에서 예외가 발생함)
Future 디자인 패턴
여기서 PoolExecutor의 특징은 Future 디자인 패턴을 사용하여 작업 실행과 결과 획득을 비동기식으로 만든다는 것입니다. 프로세스.
먼저 submit/map을 통해 작업을 작업 대기열에 넣은 다음 작업이 실행되기 시작했습니다! 그런 다음 필요할 때 future를 통해 결과를 얻거나 직접 add_done_callback(fn)을 얻습니다.
이 작업은 새 작업자에서 실행됩니다. 메인 프로세스/스레드는 차단되지 않으므로 메인 스레드가 다른 작업을 수행할 수 있습니다. 이 접근 방식을 비동기 프로그래밍이라고 합니다.
Offscreen
concurrent.futures는 multiprocessing.pool을 기반으로 구현되므로 실제로 스레드/프로세스 풀을 직접 사용하는 것보다 약간 느립니다. 하지만 보다 편리하고 간결한 API를 제공합니다.
위 내용은 Python 동시성에서 PoolExecutor 소개(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!