io密集型和cpu密集型_一次说明白Python爬虫中多线程,多进程,异步IO编程

图/文:迷神

我们在Python爬虫中,重要的是讲究速度,如果有10万或者100万Url地址,写过爬虫的都会知道,那估计是非常慢的。我们的Python爬虫一般IO密集型业务,Python爬虫程序需要发起网络请求,必然就有网络IO阻塞,通常请求一个URL耗时要几百毫秒到几秒,逐步执行,和我们CPU那么高性能比起来,那真是天壤之别。

比如,我们Python爬虫在单线程同步爬取过程中,一个个的爬取网站所有的URL,假设100个URL,平均每个URL请求的时间是1秒,那么在单线程同步场景下,最快也需要100秒钟,才能把所有的页面爬取下来。

在网页数据爬取以后,发现在数据量不大的时候,这种普通的程序还勉强,如果想极大提高速度,做到 快速爬虫,就需要使用多线程,多进程,异步IO编程了。不过,Python中有一个臭名昭著的GIL,导致做不到真正的并行运算,多核无法真正利用起来。多线程在切换线程,还有切换成本,以及线程的创建成本。如果使用多进程,虽然能利用多核处理的优势,但是多进程的创建本城比线程更高,而IO密集型任务,CPU不是瓶颈。

鉴于此,Python3.4 还是引入了异步 asyncio 模块,增加了异步编程,跟 JavaScript 的async/await 极为类似,大大方便了异步任务的处理。异步编程使得CPU不再需要再去等待耗时的操作,而是让出CPU时间给其他任务执行,可以极大提高完成所有的任务速度。

下面,我们通过具体的小例子,来看看多线程,多进程,异步IO编程的区别:

1、普通同步,单线程阻塞

单线程版本,所有的任务,按照顺序依次等待执行。

893bffa3dac94413a9c4d3a321ff48df

单线程

结果如下:

4e880b3edc5a416aa03d18a03541f9f1

结果

可以发现,总共5个任务,他们每个任务执行时间是1秒钟,单进程阻塞时,总共耗时是5秒多一点点。

2、多线程版本任务

简单来说就是在一个进程里面,可以执行多个任务,在这里的每一个任务就是一个线程。

e80b8229276440c28ff34f13661f25d1

多线程任务

执行结果:

2a738bae0dc140499c1f9f5e8ee38c01

执行结果

换成多线程之后,5个线程各负责一个任务。我们看到执行结果:1.0039010047912598 已经明显比第一个快很多了。即使有GIL

多进程版本任务

多进程就是你的电脑允许运行多个程序,在同一段时间里面,可以 “同时” 执行多个任务。

06a7f8aaae7c4b68bb19dc5a60ce640f

多进程版本

执行结果:

5c1fc09b4ccf4536ba97f364a521392d

直接结果

执行结果:1.7484214305877686。是不是很奇怪,使用多进程,时间比多线程更慢,为什么?因为创建进程的成本是要比线程高的,虽然,它可以利用多核CPU的优势。

异步版本多个任务

最后,我们来看看异步模式下,怎么样。

a8da9ed5db14411198f9eb5f627a9ee7

异步

执行结果:

de2edc3f92fb4276a5ebe5fddfd39850

执行结果

发现使用asyncio所花的时间是最少的。asyncio可以实现单线程并发IO操作,它没有多线程和进程的创建成本,就是在单线程环境下,切换任务,当这个任务被阻塞时,立刻切换其他任务,当前面的任务完成时,在通知它,这样效率就极大的提高了。

最后,值得一说的就是一个不错的HTTP框架:aiohttp,它是一个基于asyncio实现的非常强大的HTTP框架,很值得学习哦。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值