GIL (Globla Interpreter Lock)
全局解释器锁
用于避免资源竞争造成数据的错乱
Python程序的执行过程
- 启动解释器进程 python.exe
- 解析你的py文件并执行它
解释器的实质其实就是一个py文件,也就是一堆代码. 相当于多个线程要调用同一个解释器代码 共享以及竞争 可能会出现错乱 所以要给解释器加互斥锁
python 中内存管理依赖于 GC(garbage conduct 一段用于回收内存的代码) 也需要一个线程
除了你自己开的线程 系统还有一些内置线程 就算你的代码不会去竞争解释器 内置线程也可能会竞争
所以必须加上锁
当一个线程遇到了I/O 同时解释器也会自动解锁 去执行其他线程 CPU会切换到其他程序
这样的话就会导致所有线程只能并发,不能 达到真正的并行,即同一时间只有一个cpu在处理事情这就会使效率降低.
代码执行的两种状态
- 阻塞i/o失去cpu的执行权(cpu要等待io的完成)
- 非阻塞 代码正常执行 当时间过长时 中途就可能自动切换 很快就会回来 (cpu的正常运行)
比如: 有16核CPU 要处理一个下载任务 网络速度慢 100k/s 文件大小为1024kb
如果你的代码中IO操作非常多 cpu性能不能直接决定你的任务处理速度
案例:
目前有三个任务 每个任务处理需一秒 获取元数据需要一小时
3个CPU 需要 一小时1秒左右
1个cpu 需要 一小时3秒左右
在IO密集的程序中 CPU性能无法直接决定程序的执行速度(用线程池)(python就应该干这种活儿)
在计算密集的程序中 CPU性能可以直接决定程序的执行速度(用进程池)
进程池
说白了就是一个装进程的容器
为什么出现
当进程很多的时候方便管理进程
什么时候用?
当并发量特别大的时候 比如双十一,淘宝
很多时候进程是空闲的 就让他进入进程池 让有任务处理时才从进程池取出来使用
进程池使用
ProcessPoolExecutor类
创建时指定最大进程数 自动创建进程
调用submit函数将任务提交到进程池中
创建进程是在调用submit后发生的
总结一下:
进程池可以自动创建进程
进程池限制最大进程数
自动选择一个空闲的进程帮你处理任务
进程什么时候算是空闲?
代码执行完算是空闲