동시 모듈의 우선 도입
concurrent.futures
모듈은 비동기 호출 인터페이스 패키지 높이를 제공합니다
ThreadPoolExecutor:
스레드 풀 비동기 호출을 제공하는
ProcessPoolExecutor:
프로세스 풀, 비동기 호출을 제공합니다
ProcessPoolExecutor 和 ThreadPoolExecutor:
두 추상 클래스 실행 프로그램에 의해 정의 된 동일한 인터페이스를 구현합니다.
둘째, 기본적인 방법
submit(fn, *args, **kwargs):
비동기 작업 제출
map(func, *iterables, timeout=None, chunksize=1)
: 루프 동작 치환 제출
shutdown(wait=True)
: 프로세스 풀 동등한 pool.close()+pool.join()
작동
- 참 = 대기 자원 회수의 완료가 계속이 완료된 후에 모든 작업을 수행 할 수있는 풀 기다립니다
- 대기 = 거짓, 즉시 반환, 그리고 작업 실행이 풀을 완료 기다립니다
- 모든 작업이 완료 될 때까지 그러나 아무리 매개 변수 값을 기다릴 이유, 전체 프로그램은 기다릴 것
- 맵은 종료 전에 제출해야합니다
result(timeout=None)
: 결과를 얻을 수
add_done_callback(fn)
: 콜백 함수
셋째, 프로세스 풀 및 스레드 풀
풀 기능 : 프로세스 또는 스레드의 수를 제한합니다.
어떤 시간 제한 : 동시 작업의 수는 컴퓨터가 감당할 수있는 것보다 훨씬 더 큰 경우, 즉 내가 프로세스 또는 스레드의 나의 수를 제한하는 것 고려해야 작업의 과도한 수를 열고 한 시간이 아니다, 서버는 보증에서 붕괴하지 않습니다.
3.1 프로세스 풀
from concurrent.futures import ProcessPoolExecutor
from multiprocessing import Process,current_process
import time
def task(i):
print(f'{current_process().name} 在执行任务{i}')
time.sleep(1)
if __name__ == '__main__':
pool = ProcessPoolExecutor(4) # 进程池里又4个进程
for i in range(20): # 20个任务
pool.submit(task,i)# 进程池里当前执行的任务i,池子里的4个进程一次一次执行任务
3.2 스레드 풀
from concurrent.futures import ThreadPoolExecutor
from threading import Thread,currentThread
import time
def task(i):
print(f'{currentThread().name} 在执行任务{i}')
time.sleep(1)
if __name__ == '__main__':
pool = ThreadPoolExecutor(4) # 进程池里又4个线程
for i in range(20): # 20个任务
pool.submit(task,i)# 线程池里当前执行的任务i,池子里的4个线程一次一次执行任务
네,지도 사용
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import os,time,random
def task(n):
print('%s is runing' %os.getpid())
time.sleep(random.randint(1,3))
return n**2
if __name__ == '__main__':
executor=ThreadPoolExecutor(max_workers=3)
# for i in range(20):
# future=executor.submit(task,i)
executor.map(task,range(1,21)) #map取代了for+submit
다섯째, 동기 및 비동기
두 가지 방법으로 작업에 제출하는 것으로 이해
동기화 : 작업을 제출, 당신은 코드의 다음 줄을 실행하기 위해, (반환 값을 얻기 위해) 할 다른 작업을 수행해야합니다
비동기 : 실행 코드의 다음 줄은 직접 실행할 수 있습니다 끝났 기다리지 말고, 일자리를 제출합니다.
동기화 : 작업 직렬 실행을 수행하는 것과 동일
비동기
from concurrent.futures import ProcessPoolExecutor
from multiprocessing import Process,current_process
import time
n = 1
def task(i):
global n
print(f'{current_process().name} 在执行任务{i}')
time.sleep(1)
n += i
return n
if __name__ == '__main__':
pool = ProcessPoolExecutor(4) # 进程池里又4个线程
pool_lis = []
for i in range(20): # 20个任务
future = pool.submit(task,i)# 进程池里当前执行的任务i,池子里的4个线程一次一次执行任务
# print(future.result()) # 这是在等待我执行任务得到的结果,如果一直没有结果,这里会导致我们所有任务编程了串行
# 在这里就引出了下面的pool.shutdown()方法
pool_lis.append(future)
pool.shutdown(wait=True) # 关闭了池的入口,不允许在往里面添加任务了,会等带所有的任务执行完,结束阻塞
for p in pool_lis:
print(p.result())
print(n)# 这里一开始肯定是拿到0的,因为我只是去告诉操作系统执行子进程的任务,代码依然会继续往下执行
# 可以用join去解决,等待每一个进程结束后,拿到他的结果
여섯째, 콜백 함수
import time
from threading import Thread,currentThread
from concurrent.futures import ThreadPoolExecutor
def task(i):
print(f'{currentThread().name} 在执行{i}')
time.sleep(1)
return i**2
# parse 就是一个回调函数
def parse(future):
# 处理拿到的结果
print(f'{currentThread().name} 结束了当前任务')
print(future.result())
if __name__ == '__main__':
pool = ThreadPoolExecutor(4)
for i in range(20):
future = pool.submit(task,i)
'''
给当前执行的任务绑定了一个函数,在当前任务结束的时候就会触发这个函数(称之为回调函数)
会把future对象作为参数传给函数
注:这个称为回调函数,当前任务处理结束了,就回来调parse这个函数
'''
future.add_done_callback(parse)
# add_done_callback (parse) parse是一个回调函数
# add_done_callback () 是对象的一个绑定方法,他的参数就是一个函数