zoukankan      html  css  js  c++  java
  • python-day37--concurrent.futures模块 实现进程池与线程池

    1.concurrent.futures模块 直接内置就是 异步的提交   ,如果你想同步也可以实现(p.submit(task,i).result()即同步执行)

    2.属性和方法:

      1.submit   提交     

      2.shutdown  关闭池的入口  等池运行结束    

     1 #进程池
     2 from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
     3 import os,time,random
     4 def task(n):
     5     print('%s is running' %os.getpid())
     6     time.sleep(2)
     7     return n**2
     8 
     9 if __name__ == '__main__':
    10     p=ProcessPoolExecutor()
    11     l=[]
    12     start=time.time()
    13     for i in range(10):
    14         obj=p.submit(task,i)
    15         l.append(obj)
    16     p.shutdown()
    17     print('='*30)
    18     # print([obj for obj in l])      # 结果 都是 future 的对象  [<Future at 0x1461d97d1d0 state=finished returned int>,
    19                                             # <Future at 0x1461d9c6438 state=finished returned int>]
    20     print([obj.result() for obj in l])
    21     print(time.time()-start)
    22 # 结果:
    23 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    24 6.206435441970825
    进程池
     1 # 线程池
     2 from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
     3 import threading
     4 import os,time,random
     5 def task(n):
     6     print('%s:%s is running' %(threading.currentThread().getName(),os.getpid()))
     7     time.sleep(2)
     8     return n**2
     9 
    10 if __name__ == '__main__':
    11     p=ThreadPoolExecutor()
    12     l=[]
    13     start=time.time()
    14     for i in range(10):
    15         obj=p.submit(task,i)
    16         l.append(obj)
    17     p.shutdown()
    18     print('='*30)
    19     print([obj.result() for obj in l])
    20     print(time.time()-start)
    21 
    22 # 结果:
    23 ==============================
    24 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    25 2.0046041011810303
    线程池

      进程池 默认个数是CPU个数,而线程池的默认个数是CPU个数的5倍

    补充:回调函数

     1 from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
     2 import requests
     3 import os
     4 import time
     5 from threading import currentThread
     6 def get_page(url):
     7     print('%s:<%s> is getting [%s]' %(currentThread().getName(),os.getpid(),url))
     8     response=requests.get(url)
     9     time.sleep(2)
    10     return {'url':url,'text':response.text}
    11 def parse_page(res):
    12     res=res.result()     #与Pool不同之处,这里的res得到的是对象,需要result一下
    13     print('%s:<%s> parse [%s]' %(currentThread().getName(),os.getpid(),res['url']))
    14     with open('db.txt','a') as f:
    15         parse_res='url:%s size:%s
    ' %(res['url'],len(res['text']))
    16         f.write(parse_res)
    17 if __name__ == '__main__':
    18     # p=ProcessPoolExecutor()
    19     p=ThreadPoolExecutor()
    20     urls = [
    21         'https://www.baidu.com',
    22         'https://www.baidu.com',
    23         'https://www.baidu.com',
    24         'https://www.baidu.com',
    25         'https://www.baidu.com',
    26         'https://www.baidu.com',
    27     ]
    28 
    29     for url in urls:
    30         # multiprocessing.pool_obj.apply_async(get_page,args=(url,),callback=parse_page)
    31         p.submit(get_page, url).add_done_callback(parse_page)
    32     p.shutdown()
    33     print('',os.getpid())
    View Code

      3. map方法

     1 from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
     2 import os,time,random
     3 def task(n):
     4     print('%s is running' %os.getpid())
     5     time.sleep(2)
     6     return n**2
     7 
     8 if __name__ == '__main__':
     9     p=ProcessPoolExecutor()
    10     obj=p.map(task,range(10))
    11     p.shutdown()
    12     print('='*30)
    13     print(list(obj))
    View Code

    3.补充:

    单线程下串行十个任务效率不一定低,如果是计算型任务,效率不会低
    
    同步异步指的是提交任务的方式
    
    同步:提交任务(纯计算任务)后在原地等着  并不是阻塞。              等待不一定是发生了阻塞:计算时间过长也会等
    
    因为gil锁,python的一个进程的多个线程不能实现并行,但是可以实现并发
    
    如果你开的线程个数在机器的承受范围之内,开线程效率高,如果不行就需要用线程池
    
    函数实现的协程:yield
    
    单线程中提高效率:看情况再说协程,如果是计算型任务你开协程来回的切,反而降低了效率
    
    协程不是真的存在

    单线程不可能同时并行两个任务,但是可以出现并发效果
  • 相关阅读:
    【bzoj3566】[SHOI2014]概率充电器 树形概率dp
    【bzoj1419】Red is good 期望dp
    【bzoj2698】染色 期望
    【bzoj2134】单选错位 期望
    【bzoj1022】[SHOI2008]小约翰的游戏John 博弈论
    【bzoj3170】[Tjoi 2013]松鼠聚会 旋转坐标系
    【bzoj2338】[HNOI2011]数矩形 计算几何
    【bzoj2085】[Poi2010]Hamsters Hash+倍增Floyd
    【bzoj1014】[JSOI2008]火星人prefix Splay+Hash+二分
    【bzoj2795】[Poi2012]A Horrible Poem Hash+分解质因数
  • 原文地址:https://www.cnblogs.com/liuwei0824/p/7459200.html
Copyright © 2011-2022 走看看