目录:
1. 多线程
2. 全局解释器锁 GIL
目录【Python程序员都知道的入门知识】
python自学之路
1. 多线程
1.1. 概述
一个进程至少有一个线程,可以同时有多个线程。
1.1.1. 线程有五种状态:
新建、就绪、运行、阻塞、死亡
Paste_Image.png
注意:由上图可以看出,线程被解除阻塞后是回到就绪状态的。
1.1.2. 线程阻塞的三种情况:
同步阻塞
等待阻塞
其他(睡眠、其他线程加入、等待IO)
1.1.3. 同步锁
因为一个进程允许同时有多个线程,多线程可能导致共享数据不同步,因此引出同步锁,用以同步共享数据
1.1.4. 线程通讯
一个进程中的多个线程之间可能需要通过通讯来为对方提供一些信息,比如说B线程需要确定在A线程中某个条件满足时才执行某些操作,需要A线程在条件满足时通知B线程,由此引出线程通讯。
1.1.5 总结
多线程大致就以上几个概念,线程状态转换、线程阻塞、线程同步、线程通讯。
那么问题来了,明明如果进程中只用一个线程,就不会存在什么共享数据不同步、线程之间要进行通讯这样的麻烦事,为什么要有多线程这东西呢?而且辣么多的编程语言都在说多线程?
使用多线程有什么好处在于:
- 将耗时操作交给后台处理
- 加快程序运行速度
- 帮助释放资源
然而,倘或多线程在python中这么优雅,大概就不会看到下面的问句了:
“为什么有人说python的多线程是鸡肋?”
“为什么在python里推荐使用多进程而不是多线程?”
说好的加快运行速度,说好的耗时操作移交后台处理,怎么变成鸡肋了呢?
总结起来大概的意思就是说:
由于Python GIL(Global Interpreter Lock)的存在:
1. 多线程对于【CPU密集型】代码未能提高效率,甚至更糟。推荐用多进程(multiprocessing)
2. 多线程对于【IO密集型】代码可以明显提高效率。可使用多线程(threading)
关于GIL,小野猫在翻阅资料过程中发现了这篇:《gil-in-python》,作者:卢钧轶(cenalulu)的文章,个人感觉不错,特此推荐。本文第二部分也将总结一些GIL的要点。
1.2. python中的多线程
在1.1中说到,虽然python多线程不那么优雅,但是多线程对于IO密集型代码还是足够友好的,因此还是应该了解一下Python的多线程。
那Python提供了thread
、threading
、queue
几个模块来实现线程操作。
需要强调的是,threading 是相对于thread 更高级的一个模块,为了避免冲突,也为了遵循择优原则,这里就不考虑thread了。
2. 全局解释器锁 GIL
GIL(Global Interpreter Lock):全局解释器锁,CPython中为了解决内存管理线程不安全而引入的一个互斥体。
2.1. 引入
我们说Python是一种脚本语言,不像Java这样的编译性语言一样要经过编译后才能运行,脚本语言不需要编译,只在运行的时候由解释器进行解释运行即可,这个解释器其实就相当于执行环境。
Python的执行环境有CPython
、PyPy
、Psyco
、IPython
、Jython
、IronPython
等等,其中运用最广泛的就是CPython了,CPython以>>>
作为提示符。我们从Python官方网站下载下来的Python自带的解释器正是CPython。
那么问题又来啦,GIL跟解释器又是什么关系呢?
准确地说,GIL并不是Python的,也就是说它不是Python的特性,它是解释器CPython的特性。由于CPython的内存管理是非线程安全的,因此才在CPython中引入了GIL这个全局锁。也就是说,如果Python开发要避开GIL,使用其他的不包含GIL的Python解释器即可。
网友评论