第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > concurrent.futures模块(进程池线程池)

concurrent.futures模块(进程池线程池)

时间:2019-01-30 02:27:02

相关推荐

concurrent.futures模块(进程池线程池)

1、线程池的概念

由于python中的GIL导致每个进程一次只能运行一个线程,在I/O密集型的操作中可以开启多线程,但是在使用多线程处理任务时候,不是线程越多越好,因为在线程切换的时候,需要切换上下文环境,这样会导致CPU的大量开销,同时产生大量的切换时间浪费。为了解决这个问题,线程池概念被提出。预先创建好一个较为优化的数量的线程,让过来的任务立刻能够使用,就形成了线程池。python中的concurrent.futures模块为我们做了很好地封装,该模块为我们封装了线程池和进程池。

2、最佳线程数的获取:

1、通过用户慢慢递增来进行性能压测,观察QPS(即每秒的响应请求数,也即是最大吞吐能力。),响应时间

2、根据公式计算:服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量

3、单用户压测,查看CPU的消耗,然后直接乘以百分比,再进行压测,一般这个值的附近应该就是最佳线程数量。

3、concurrent.futures模块中的线程池

from concurrent.futures import ThreadPoolExecutorimport time,osdef fn(name):print('%s %s is running' %(name,os.getpid()))time.sleep(3)if __name__=="__main__":p=ThreadPoolExecutor(5) #设置线程池线程数for i in range(10):obj=p.submit(fn,'线程pid:') #submit(fn, *args, **kwargs)res=obj.result() #注意:submit提交后返回的结果是一个future对象,需要使用obj.result才能获取想要的字符串等结果p.shutdown(wait=True) # 关闭线程池的入口,等待池内任务运行结束

4、concurrent.futures模块中的进程池

from concurrent.futures import ProcessPoolExecutorimport time,osdef fn(name):print('%s %s is running' %(name,os.getpid()))time.sleep(3)if __name__=="__main__":p=ProcessPoolExecutor(5) #设置进程池线程数for i in range(10):obj=p.submit(fn,'进程pid:') #submit(fn, *args, **kwargs)res=obj.result() #注意:submit提交后返回的结果是一个future对象,需要使用obj.result才能获取想要的字符串等结果p.shutdown(wait=True) # 关闭进程池的入口,等待池内任务运行结束

5、多线程的+回调函数执行

from concurrent.futures import ThreadPoolExecutorimport requestsdef fetch_async(url):response = requests.get(url)return response#返回执行结果对象def callback(future): print(future.result()) #future 相当于将上面函数执行结果对象response传递进去执行.result()方法url_list = ['', '']pool = ThreadPoolExecutor(5)for url in url_list:v = pool.submit(fetch_async, url)v.add_done_callback(callback) #执行对象的回调函数pool.shutdown(wait=True)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。