一、进程池与线程池

实现并发的手段有两种,多线程和多进程。注:并发是指多个任务看起来是同时运行的。主要是切换+保存状态。

当我们需要执行的并发任务大于cpu的核数时,我们需要知道一个操作系统不能无限的开启进程和线程,通常有几个核就开几个进程,如果进程开启过多,就无法充分利用cpu多核的优势,效率反而会下降。这个时候就引入了进程池线程池的概念。

池的功能就是限制启动的进程数或线程数

concurent.future模块:

concurrent.futures模块提供了高度封装的异步调用接口

ProcessPoolExecutor: 进程池,提供异步调用

p = ProcessPoolExecutor(max_works)对于进程池如果不写max_works:默认的是cpu的数目,默认是4个

ThreadPoolExecutor:线程池,提供异步调用   
p = ThreadPoolExecutor(max_works)对于线程池如果不写max_works:默认的是cpu的数目*5

 

补充:

提交任务的两种方式:
# 同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行的
# 异步调用:提交完一个任务之后,不在原地等待,结果???,而是直接执行下一行代码,会导致任务是并发执行的

进程池从无到有创建进程后,然后会固定使用进程池里创建好的进程去执行所有任务,不会开启其他进程

# 基本方法
#submit(fn, *args, **kwargs)
异步提交任务

#map(func, *iterables, timeout=None, chunksize=1) 
取代for循环submit的操作

#shutdown(wait=True) 
相当于进程池的pool.close()+pool.join()操作
wait=True,等待池内所有任务执行完毕回收完资源后才继续
wait=False,立即返回,并不会等待池内的任务执行完毕
但不管wait参数为何值,整个程序都会等到所有任务执行完毕
submit和map必须在shutdown之前

#result(timeout=None)
取得结果

#add_done_callback(fn)
回调函数
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import time,random,os
import requests


def get(url):
    print('%s GET %s' %(os.getpid(),url))
    time.sleep(3)
    response=requests.get(url)
    if response.status_code == 200:
        res=response.text
    else:
        res='下载失败'
    return res

def parse(future):
    time.sleep(1)
    res=future.result()
    print('%s 解析结果为%s' %(os.getpid(),len(res)))

if __name__ == '__main__':
    urls=[
        'https://www.baidu.com',
        'https://www.sina.com.cn',
        'https://www.tmall.com',
        'https://www.jd.com',
        'https://www.python.org',
        'https://www.openstack.org',
        'https://www.baidu.com',
        'https://www.baidu.com',
        'https://www.baidu.com',

    ]

    p=ProcessPoolExecutor(9)

    start=time.time()
    for url in urls:
        future=p.submit(get,url)
        # 异步调用:提交完一个任务之后,不在原地等待,而是直接执行下一行代码,会导致任务是并发执行的,,结果futrue对象会在任务运行完毕后自动传给回调函数
        future.add_done_callback(parse)  #parse会在任务运行完毕后自动触发,然后接收一个参数future对象

    p.shutdown(wait=True)


    print('',time.time()-start)
    print('',os.getpid())
test

相关文章:

  • 2022-12-23
  • 2022-02-07
  • 2022-12-23
  • 2022-12-23
  • 2021-11-27
  • 2022-12-23
猜你喜欢
  • 2021-08-29
  • 2022-01-09
  • 2021-07-30
  • 2022-12-23
  • 2021-05-19
  • 2022-12-23
相关资源
相似解决方案