(1条消息) python3爬虫系列14之进程、单进程、多进程、线程、单线程、多线程、并行、并发、互斥锁、协程的白话解释
python3爬虫系列14之进程、单进程、多进程、线程、单线程、多线程、并行、并发、互斥锁、协程的白话解释
1. 前言回顾
到目前为止,实际上我们的爬虫进程总共介绍了:
爬虫架构——确认目标(爬虫对象)——分析网页(抓包分析,URL咋变的,什么参数?)——请求网页(requests库)——解析网页(bs4,lxml)——提取内容(xpath,css selector,re,find,find_all)——封装内容(转json,转dict)——本地写入(txt,csv,json,html)——入库(mysql)——可视化绘图(pyecharts)的整个简单流程。
而在上一篇说的是,
python3爬虫系列13之find_all爬虫高考分数线并绘制分析图(普通版),
在网页数据爬取以后,发现在数据量不大的时候,这种普通的程序依然速度很慢,那么想要做到 快速爬虫,就需要知道
- 什么是进程?
- 什么是单进程?
- 什么是多进程
- 什么是线程
- 什么是单线程
- 什么是多线程
- 什么是并行
- 什么是并发
- 什么是互斥锁
- 什么是协程
使用它们,进程、单进程、多进程、线程、单线程、多线程、并行、并发、互斥锁、协程。往往可以 让我们的爬虫程序加速冲刺。
OMG,这么多?要学个三五十年吧?放心了,我只说总结,不啰嗦。(因为我也不看源码。。。)
2.什么是进程
进程就是正在运行的程序
比如你的电脑系统现在正在运行着的QQ(酷狗,微信啥子随便了。)就是一个进程。
一旦你的「QQ」运行起来,系统就会给「QQ」分配了内存和资源。
进程和进程之间是互相独立的,分配的空间也不交集。
3.什么是单进程
单进程就是你的电脑太破,只允许运行一个程序。其他的运行就炸。
简单来说就是电脑只能做一件事情.比如电脑打开了QQ,就不能再去打开淘宝。
4.什么是多进程
多进程就是你的电脑允许运行多个程序,在同一段时间里面
可以 “同时” 执行多个任务。
简单来说就是电脑可以同一时间在做很多事情,一边玩听歌一边看片。
原理就是你的CPU 在做进程之间的切换,因为CPU 的切换速度超级快,快到让你感觉到,开着的所有程序好像是在同时运行。
这样就提高了 CPU 的使用率了,所有代码后期都爱提及多进程。同理你的爬虫就可以使用多进程。
5.什么是线程
线程是比进程更小的一个单位,可以说是程序用 CPU 的一个基本单元。它存在于进程之中,而且有很多兄弟伙。
简单来说就是在一个进程里面,可以执行多个任务,在这里的每一个任务就是一个线程。
6.什么是单线程
单线程是一个程序里,如果只是单一的一个执行路径,那么它就是单线程的。就是什么,你是个独生子。
简单来说就是在一个进程里面,要执行多个任务,但是呢,完成任务的方式只有一个单一的执行路径,那么它就是单线程的。
7.什么是多线程
单线程是一个程序里,如果只是单一的一个执行路径,那么它就是单线程的。就是什么,你是个独生子。
简单来说就是在一个进程里面,要执行多个任务,但是呢,完成任务的方式有多个执行路径,那么它就是多线程的。
So:
想要让爬虫更高效,就可以让你的爬虫实现多线程。
既然说到了线程,自然离不开并行和并发。
8.什么是并行
在某一个【时间段内】,可以同时执行多个进程,这就是并行。
简单来说,一个单核的 CPU每次只能执行一个进程,那么一个多核的 CPU,就可以同时执行多个进程了。这样这些同时运行的多个进程,就是一种并行方式。
9.什么是并发
在某一个【时间点】,同时执行多个进程,这就是并发。
简单来说就是 在 双十一的时候,晚上的 12 点,大伙的女朋友们都在握着手机,准备同时秒杀某一个商品。这个多人一起抢一个东西,就是一种并行方式。
10.什么是互斥锁
保安,让线程别他妈乱来,排好队,一个一个线程安全有序的去执行。
在系统里面,进程和进程之间是互相独立的,而我们知道,一个进程里面有多个线程,而线程之间却是共享一个进程空间的。
简单来说,
你想啊,一个蛋糕好多个线程一起分,劳资又不是恐龙,谁都不让,难免就有一些线程就要搞事情了。
于是好多线程都暴动了,这样数据就不安全了,所以就有了互斥锁的出现。
它的作用就是让线程别他妈乱来,排好队,一个一个线程安全有序的去执行。
很多开发语言中都有这个互斥锁的存在。名字可能不一样哟。
10.1 在Python中的互斥锁:GIL 锁
有了互斥锁的出现,python中取了个别名叫GIL :全称是 Global Interpreter Lock(全局解释器锁)。
就是用来控制线程执行权限的,线程需要执行的时候,要先获得 GIL 之后才可以执行,这样就不会产生线程安全问题。
这东西设计之初的考虑,为了数据安全所做的决定。某个线程想要执行,必须先拿到 GIL,我们可以把 GIL 看作是“通行证”,并且在一个
Python 进程中,GIL 只有一个。拿不到通行证的线程,就不允许进入 CPU 执行。
so:
在 Python 中,无论是单核还是多核,都同时只能有一个线程在执行。其根源就是因为 GIL 锁的存在。
相比python,其他语言(比如java)CPU 是多核时是支持多个线程同时执行。尴尬了。
10.2 在 I/O 流阻塞时,GIL会被释放
上面我们知道了在python中因为 GIL 锁,我们同时只能有一个线程在执行。
这意味着多线程还有个毛用啊?
此时,python提出了另外一个特性:在 I/O 流阻塞的时候,GIL会被释放。(GIL被炒鱿鱼了)
(所谓I/O流就是输入输出流)
什么意思呢?
就是说以后你写Python 程序:
如果是要处理一些【输入输出的多任务】,在 I/O 流阻塞的时候,GIL会被释放,相对于GIL被炒鱿鱼了,就可以开启多线程。
如果是要处理【多任务】,想要充分的去利用我们多核的CPU,就开启多进程。因为对于频繁的cpu操作,由于GIL锁的原因,多个线程只能用一个cpu,这时多进程的执行效率要比多线程高。
11.什么是协程(微线程)
协程也叫微线程。
在一个线程里面可以执行多个函数,线程和进程是通过系统调度的(也就是函数之间由系统来自行调度,开销小)。
而协程(微线程)不需要通过系统调度,可以根据需要自己调度。(因为微线程是函数之间在切换,所以开销更小)。
在 python 中使用微线程时一般会用到 (genvent、monkey.patch_all)
最后
python什么时候使用多线程,什么时候使用多进程?
多线程使用场景:IO密集型- 输入输出处理(频繁读取文件,读取网络套接字),大多时间是在等待。io 操作不占用CPU(从硬盘、从网络、从内存读数据都算io,网络并发这一类的。
多进程使用场景:CPU密集型-绝大多数时间在数学与逻辑运算,比如批量爬取很多数字,文本数据,求平均值,数据分析等。
小提示:Python中 time.sleep 是阻塞的,都知道使用它要谨慎,但在多线程编程中,time.sleep 并不会阻塞其他线程。使用os.system(‘pause’)
本篇就到这里,主要理解这几个概念,下一篇使用多进程、多线程、协程的方式来实现 python 的爬虫。