没有合适的资源?快使用搜索试试~ 我知道了~
大家都知道当任务过多,任务量过大时如果想提高效率的一个最简单的方法就是用多线程去处理,比如爬取上万个网页中的特定数据,以及将爬取数据和清洗数据的工作交给不同的线程去处理,也就是生产者消费者模式,都是典型的多线程使用场景。 那是不是意味着线程数量越多,程序的执行效率就越快呢。 显然不是。线程也是一个对象,是需要占用资源的,线程数量过多的话肯定会消耗过多的资源,同时线程间的上下文切换也是一笔不小的开销,所以有时候开辟过多的线程不但不会提高程序的执行效率,反而会适得其反使程序变慢,得不偿失。 所以,如何确定多线程的数量是多线程编程中一个非常重要的问题。好在经过多年的摸索业界基本已形成一套默认的标准。
资源详情
资源评论
资源推荐
实例代码讲解实例代码讲解Python 线程池线程池
大家都知道当任务过多,任务量过大时如果想提高效率的一个最简单的方法就是用多线程去处理,比如爬取上万个网页中的特
定数据,以及将爬取数据和清洗数据的工作交给不同的线程去处理,也就是生产者消费者模式,都是典型的多线程使用场景。
那是不是意味着线程数量越多,程序的执行效率就越快呢。
显然不是。线程也是一个对象,是需要占用资源的,线程数量过多的话肯定会消耗过多的资源,同时线程间的上下文切换也是
一笔不小的开销,所以有时候开辟过多的线程不但不会提高程序的执行效率,反而会适得其反使程序变慢,得不偿失。
所以,如何确定多线程的数量是多线程编程中一个非常重要的问题。好在经过多年的摸索业界基本已形成一套默认的标准。
对于 CPU 密集型的计算场景,理论上将线程的数量设置为 CPU 核数就是最合适的,这样可以将每个 CPU 核心的性能压榨到
极致,不过在工程上,线程的数量一般会设置为 CPU 核数 + 1,这样在某个线程因为未知原因阻塞时多余的那个线程完全可
以顶上。
而对于 I/O 密集型的应用,就需要考虑 CPU 计算的耗时和 I/O 的耗时比了。如果 I/O 耗时和 CPU 耗时 为 1:1,那么两个线程
是最合适的,因为当 A 线程做 I/O 操作时,B 线程执行 CPU 计算任务,当 B 线程做 I/O 操作时,A 线程执行 CPU 计算任
务,CPU 和 I/O 的利用率都得到了百分百,完美。所以可以认为最佳线程数 = CPU 核数 * [1 +(I/O 耗时 / CPU 耗时]。
线程池线程池
平时我们自己写多线程程序时基本都是直接调用 Thread(target=method) 即可,实际上创建线程远没有这么简单,需要分配内
存,同时线程还需要调用操作系统内核的 API,然后操作系统还需要为线程分配一系列的资源,过程很是复杂,所以要尽量避
免频繁的创建和销毁线程。
回想一下自己平时写多线程代码的模式,是不是当任务来临时直接创建线程,执行任务,当任务执行结束之后,线程也就随之
消亡了。然后又开始循环往复。有多少个任务就创建了多少个线程。这种模式的话很浪费硬件资源。
那如何避免这种问题呢,线程池就派上用场了。
其实线程池就是生产者消费者模式的最佳实践,当线程池初始化时,会自动创建指定数量的线程,有任务到达时直接从线程池
中取一个空闲线程来用即可,当任务执行结束时线程不会消亡而是直接进入空闲状态,继续等待下一个任务。而随着任务的增
加线程池中的可用线程必将逐渐减少,当减少至零时,任务就需要等待了。
在 python 中使用线程池有两种方式,一种是基于第三方库 threadpool,另一种是基于 python3 新引入的库
concurrent.futures.ThreadPoolExecutor。这里我们都做一下介绍。
threadpool 方式方式
使用 threadpool 前需要先安装一下,看了这么久我们的文章,相信你很快就会搞定的。在命令行执行如下命令即可。
pip install threadpool
以下是一个简易的线程池使用模版,我们创建了一个函数 sayhello,然后创建了一个大小为 2 的线程池,也就是线程池总共有
两个活跃线程。
最后通过 pool.putRequest() 将任务丢到线程池执, pool.wait() 等待所有线程结束。同时我们还可以定义回调函数,拿到任务的返
回结果。
由结果我们可以看出,线程池中的确只有两个线程,分别为 Thread-1 和 Thread-2。
import time
import threadpool
import threading
def sayhello(name):
print("%s say Hello to %s" % (threading.current_thread().getName(), name));
time.sleep(1)
return name
def callback(request, result): # 回调函数,用于取回结果
print("callback result = %s" % result)
name_list =['admin','root','scott','tiger'] start_time = time.time()
pool = threadpool.ThreadPool(2) # 创建线程池
requests = threadpool.makeRequests(sayhello, name_list, callback) # 创建任务
[pool.putRequest(req) for req in requests] # 加入任务
pool.wait()
print('%s cost %d second' % (threading.current_thread().getName(), time.time()-start_time))
weixin_38535428
- 粉丝: 2
- 资源: 934
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于matlab的考虑设备动作损耗的配电网分布式电压无功优化源码.zip
- 互联网网络科技类网站模板整站打包下载.zip
- 电脑操作系统软件下载网站模板打包整站下载.zip
- 创维e910 mt8685刷机包
- 网站整站模板竞技游戏类网站模板打包下载.zip
- 14 Day of the Dragon King - Mary Pope Osborne.png
- 【Redis开发】资源Redis-v6.0.20.zip
- 《STM32单片机+DHT11温湿度++光敏电阻+蜂鸣器+OLED屏幕》源代码
- (完整版)银行计算机储蓄系统需求分析.doc
- 图像超分辨率FSRCNN的最优SSIM和PSNR的模型权重文件(x2、x3、x4)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0