线程池与进程池

  • 线程池的创建需要导入模块

    1
    from concurrent.futures import ThreadPoolExecutor
  • 创建一个线程池,并且指定最大的线程数

    1
    executor = ThreadPoolExecutor(max_workers=3)
  • 返回任务句柄task1,可对task查看任务状态

    1
    task = executor.submit(get_html, 1) 

​ 向线程池中提交函数,线程池会自动分配任务,第一位是函数名,后面全是参数

​ submit函数立即执行,不会阻塞主线程

  • 检查任务是否完成

    1
    task.done()
  • 取消任务的执行,该任务没有放入线程池才能成功取消

    1
    task.cancel()
  • 拿到任务执行结果,是个阻塞方法,可通过timeout设置超时时间

    1
    task.result()
  • as_comoleted是一个生成器,会阻塞,知道所有任务执行完成,也就是说每个任务执行完成就会迭代,然后阻塞

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    from concurrent.futures import ThreadPoolExecutor, as_completed, wait, ALL_COMPLETED, FIRST_COMPLETED
    executor = ThreadPoolExecutor(max_workers=3)
    def get_html(times):
    time.sleep(times)
    print('获取网页完毕,执行{}s'.format(times))

    urls = [4, 2, 3]
    all_task = [executor.submit(get_html, url) for url in urls]
    for item in as_completed(all_task):
    data = item.result()
    print("主线程中获取任务的返回值是{}".format(data))
    for data in executor.map(get_html, urls):
    print("主线程中获取任务的返回值是{}".format(data))
    #map会把任务和参数映射
    wait(all_task, return_when=ALL_COMPLETED) #主线程等待,知道满足什么条件时继续执行

    as_completed和map的区别,它们都能拿到任务的完成结果,但是as_completed会根据任务的快慢返回结果,map不管任务快慢,严格按照传参顺序返回结果

  • 进程池

    进程有两种实现方式,一种与线程用法完全相同,也是从concurrent.futures ProcessExecutePool

    另一种为multiprocessing

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import multiprocessing
    import time

    def get_html(n):
    time.sleep(n)
    print("{}子进程获取内容成功".format(n))
    return n

    if __name__ == '__main__':
    #通过cpu_count获取当前主机的核心数
    pool = multiprocessing.Pool(multiprocessing.cpu_count())
    #异步方法
    result = pool.apply_async(get_html, args=(3,))
    pool.close()
    #必须在join前调用此方法
    pool.join()
    result.get()
    #子进程执行的结果
    #imap_unordered 无序先完成的先输出
    for result in pool.imap(get_html, [1, 2, 3]):
    print("{}休眠执行成功".format(result))