python性能优化,GIL理解
Cpython和GIL
GIL, Global Interpreter Lock
- Cpython解释器的内存管理并不是线程安全的
- 保护多线程情况下对python对象的访问
- Cpython解释器使用简单的琐机制避免多个线程同时访问字节码(python是把源文件编译成字节码去执行的)
所以就造成了在一个时刻只有一个线程可以执行字节码,无法利用cpu的多核
GIL的影响
主要就是限制了程序的多核执行
- 同一个时间只有一个线程执行字节码
- CPU密集型程序难以利用多核优势
- IO期间会释放GIL, 对IO密集的程序影响不大(在进行IO操作的时候,GIL被释放,就可以切换不同的线程执行字节码,这也是为什么python可以用来做web开发
如何规避GIL的影响
首先要区分是CPU密集还是IO密集
- CPU密集型可以使用多进程 + 进程池
- IO密集可以使用多线程和协程
- cpython扩展(把python转换成c语言来跑)
为什么有了GIL还要关注线程安全
Python中什么操作才是原子的(一步到位执行完)?
GIL 的作用是:对于一个解释器,只能有一个线程在执行字节码。所以每时每刻只有一条字节码在被执行一个线程。GIL保证了字节码 这层面上是线程安全的。
但是如果你有个操作比如 x += 1,这个操作需要多个字节码操作,在执行这个操作的多条字节码期间的时候可能中途就换线程了,这样就会出现问题。
可以通过 dis 库来查看字节码操作过程。
- 一个操作如果是一个字节码指令可以完成的,那就是原子的。
- 原子性可以保证线程安全的
服务端性能优化措施
web应用语言一般不会成为瓶颈
- 数据结构和算法
- 数据库层:索引优化,慢查询消除,批量操作减少IO, 引入NoSql提升性能。
- 网络IO: 批量操作,pipline操作减少IO
- 使用内存数据库设置缓存: redis/memcached
- 异步:asyncio,celery
- 并发:gevent/多线程