协程python的救星!!!
程序员文章站
2024-02-23 09:04:40
...
python中有了进程和线程为什么还要协程呢?
-
协程是程序员写调度逻辑的,不需要CPU进行线程的切换,因此也就省下了切换上下文的开销,提升了性能。
-
同时协程不需要使用多线程中的锁机制,只有一个线程,因此在协程中控制共享资源时不需加锁,所以执行效率也比多线程高。
-
协程其实就是一个单线程,那么自然它也无法利用多核资源。因此在现实中,我们通常是使用多进程+协程的方法,这样既充分的利用多核的优势,又充分发挥协程的高效率,从而获得高性能。
下来我们了解一下python中怎么实现协程的并发:
yield实现:
# encoding:utf-8
import time
def consumer(name):
print('消费者准备吃包子--')
while True:
new_baozi=yield #接受调用生成器的值
print("{}吃了第{}个包子".format(name,new_baozi))
time.sleep(1)
def producer(name):
s1.__next__()
s2.__next__()
count=1
while True:
print("{}做了第{}包子和第{}包子".format(name,count,count+1))
s1.send(count) #传值给yield
s2.send(count+1)
count+=2
if __name__ == '__main__':
s1=consumer('张三')
s2=consumer('李四')
producer('郭大厨')
greenlet来实现:
# encoding:utf-8
from greenlet import greenlet
def text1():
print('text1')
gr2.switch() # 暂停 执行 gr2
print('text1-2')
gr2.switch()
def text2():
print('text2')
gr1.switch()
print('text2-2')
# 将需要执行的函数 封装到greenlet里面
gr1 = greenlet(text1)
gr2 = greenlet(text2)
# 执行那个函数就switch那个
gr1.switch()
gevent来实现:
gevent其原理是当一个greenlet遇到IO(指的是input output 输入输出,比如网络、文件操作等)操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行,不像greenlet需要人工切换。
# encoding:utf-8
import gevent,random
def demo(num):
for i in range(num):
print(gevent.getcurrent(),i)
gevent.sleep(int(random.random()))
s1=gevent.spawn(demo,3) #第一个参数 函数名 第二个是传入函数的参数
s2=gevent.spawn(demo,5)
s3=gevent.spawn(demo,6)
s1.join()
s2.join()
s3.join()
运行结果:
<Greenlet at 0x11571e6a8: demo(3)> 0
<Greenlet at 0x11571e7b8: demo(5)> 0
<Greenlet at 0x11571e8c8: demo(6)> 0
<Greenlet at 0x11571e6a8: demo(3)> 1
<Greenlet at 0x11571e7b8: demo(5)> 1
<Greenlet at 0x11571e8c8: demo(6)> 1
<Greenlet at 0x11571e6a8: demo(3)> 2
<Greenlet at 0x11571e7b8: demo(5)> 2
<Greenlet at 0x11571e8c8: demo(6)> 2
<Greenlet at 0x11571e7b8: demo(5)> 3
<Greenlet at 0x11571e8c8: demo(6)> 3
<Greenlet at 0x11571e7b8: demo(5)> 4
<Greenlet at 0x11571e8c8: demo(6)> 4
<Greenlet at 0x11571e8c8: demo(6)> 5
上一篇: MySQL命令行删除表中的一个字段
下一篇: 老生常谈java垃圾回收算法(必看篇)