python中的线程竟然是伪线程,确实这是毋庸置疑的,这是作为一名程序员的我今天才知道的,为什么会这样呢?
原因在于刚开始python语言的开发时候,电脑用的是单核CPU,而python语言的设计者设计了一个GIL,用它来作为一个排它锁,以便完成计算机的任务。
随着CPU核数的增多,python开发人员也意识到这个问题,当时python开发的原班人马也想修改GIL,但是最后还是放弃了,因为GIL作为python开发的源头机制牵扯的东西太多,修改难度太高。他们修改的是python语言解释器。那么什么是python语言解释器,以及python文件是怎么运行的呢?
废话不说,上图:
python语言解释器,就是把程序员能看懂的语言(简单来说是相对高级的语言)转换成电脑能看懂的语言(机器语言),相当于一个翻译官,把人说的话翻译给鸟听翻译给鱼听等等。
那么问题来了,计算机语言包括哪些呢?
哈哈,上图吧!
简单来说是这样,深入的话百度比我解释的要详细。
因此python语言产生了一个缺点-----速度慢效率差,这可能是当时python语言解释器是基于单核CPU的机制所引起的。但是python也具有自己明显的优点,因为拥有大量的三方库,所以开发简单高效。
为了解决这个问题python的开发人员又研究出一种新的机制---协程,协程这个东西貌似是python独有的(读书少不敢太确定),协程这个东西比线程要小,所以又叫微线程,微线程是比线程更小的调度单位。
协程有两种实现方式:(1)通过yield实现 (2)通过greentlet实现
第一种方式的实现代码如下:
import time
from greenlet import greenlet
def consumer(name):
while True:
baozi=yield #yield有返回和中断的能力
print("%s--吃了包子%d"%(name,baozi))
time.sleep(1)
def producer():
# r=c1.__next__()
# r=c2.__next__()
c1.__next__()
c2.__next__()
n=1
while True:
print("厨师一下生产两个包子------生产了包子%d"%(n))
c1.send(n)
c2.send(n+1)
n+=2
if __name__ == '__main__':
c1=consumer("c1")
c2=consumer("c2")
p=producer()
第二种实现方式:
from greenlet import greenlet
def test1():
print("10")
# 切换gr2中执行
gr2.switch()
print("12")
# 切换gr2中执行
gr2.switch()
def test2():
print("11")
# 切换gr1中执行
gr1.switch()
print("13")
#把要执行的代码放入greenlet()中
gr1=greenlet(test1)
gr2=greenlet(test2)
#切换gr1中执行
gr1.switch()
方式二的结果为 10,11,12,13
在这里说明一下:协程是一个单独的执行单元,自带CPU上下文,什么意思呢,简单来说就是可以记忆自己上次执行的状态,以及下下次应该执行什么代码。比如下图:
在斐波那契函数中每次运行next(),就会出来一个值,就是因为他记忆了自己上次运行的状态,要不然就会丢失数据了。
更简明来说yield就是分割上下文的地方。