人人都能学会的 Python 多线程指南
来源:早起Python
作者:刘早起
在 Python 中 , 多线程最常见的一个场景就是爬虫 , 例如这样一个需求 , 有多个结构一样的页面需要爬取 , 例如下方的URL(豆瓣阿凡达影评 , 以10个为例)
url_list = [
'https://movie.douban.com/subject/1652587/reviews?sort=time&start=0',
'https://movie.douban.com/subject/1652587/reviews?sort=time&start=20',
'https://movie.douban.com/subject/1652587/reviews?sort=time&start=40',
'https://movie.douban.com/subject/1652587/reviews?sort=time&start=60',
'https://movie.douban.com/subject/1652587/reviews?sort=time&start=80',
'https://movie.douban.com/subject/1652587/reviews?sort=time&start=100',
'https://movie.douban.com/subject/1652587/reviews?sort=time&start=120',
'https://movie.douban.com/subject/1652587/reviews?sort=time&start=140',
'https://movie.douban.com/subject/1652587/reviews?sort=time&start=160',
'https://movie.douban.com/subject/1652587/reviews?sort=time&start=180']
如果依次爬取 , 请求第一个页面——得到返回数据——解析数据——提取、存储数据——请求第二个页面 , 按照这样的思路 , 那么大量时间都会浪费在请求、返回数据上 , 如果在等待第一个页面返回数据时去请求第二个页面 , 就能有效的提高效率 , 多线程就可以实现这样的功能 。
在Python中实现多线程的方法也很多 , 我将基于 threading 模块一点一点介绍 , 注意本文不会太注重于多线程背后的技术概念(面试常问) , 仅希望用最少的话教会大家如何实现 。当然会在最后介绍如何使用threading模块来解决上面的爬虫问题 。
threading基本使用
让我们先从一个简单的例子开始 , 定义do_something函数 , 执行该函数需要消耗1秒
import time
start = time.perf_counter()
def do_something():
print("-> 线程启动")
time.sleep(1)
print("-> 线程结束")
do_something()
finish = time.perf_counter()
print(f"全部任务执行完成 , 耗时 {round(finish - start,2)} 秒")
上面的代码不难理解 , 执行do_something并计算耗时 , 结果很明显应该是1s
-> 线程启动
-> 线程结束
全部任务执行完成 , 耗时 1.01 秒
现在如果需要执行两次do_something , 按照最基本的思路
import time
start = time.perf_counter()
def do_something():
print("-> 线程启动")
time.sleep(1)
print("-> 线程结束")
do_something()
do_something()
finish = time.perf_counter()
print(f"全部任务执行完成 , 耗时 {round(finish - start,2)} 秒")
执行上面代码结果也很容易猜到是2秒
-> 线程启动
-> 线程结束
-> 线程启动
-> 线程结束
全部任务执行完成 , 耗时 2.01 秒
这就是最常规的 同步 思路 , 在CPU执行第一个函数 , 也就是等待1s的时间内 , 什么也不干 , 等第一个函数执行完毕后再执行第二个函数
文章图片
文章图片
很明显 , 这样让CPU干等着啥也不干并不是一个很好的选择 , 而多线程就是解决这一问题的方法之一 , 让CPU在等待某个任务完成时去执行更多的操作 , 将整个过程简化为下图流程 , 这样就能充分节省时间
文章图片
文章图片
现在使用threading来通过多线程的方式实现上面的过程 , 非常简单 , 定义两个线程并依次启动即可
import time
import threading
start = time.perf_counter()
def do_something():
print("-> 线程启动")
time.sleep(1)
print("-> 线程结束")
thread1 = threading.Thread(target=do_something)
- 人类与AI如何共处?诺奖科学家、将棋天才、“低欲望社会”提出者的不同解答
- 冬奥在即!“AI教练”、滑雪机器人,沪上高校科技助力“冰雪精灵”!
- canalys公布2021年全球个人电脑市场数据
- 九部门:严打平台企业超范围收集个人信息行为
- 年会礼品怎么选?不妨看看讯飞智能录音笔SR702、人体工学椅
- 空匣人型安定值怎么削减(空匣人型安定值降低方法分享)
- 249克!开箱道通EVO Nano+袖珍无人机:夜景是亮点
- 集五福更方便,支付宝为视障人群推出“摇一摇”领福卡
- 克服天然缺陷!人工高效生物固氮技术潜力巨大
- 毕节人,囤年货啦