欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

协程python的救星!!!

程序员文章站 2024-02-23 09:04:40
...

python中有了进程和线程为什么还要协程呢?

  1. 协程是程序员写调度逻辑的,不需要CPU进行线程的切换,因此也就省下了切换上下文的开销,提升了性能。

  2. 同时协程不需要使用多线程中的锁机制,只有一个线程,因此在协程中控制共享资源时不需加锁,所以执行效率也比多线程高。

  3. 协程其实就是一个单线程,那么自然它也无法利用多核资源。因此在现实中,我们通常是使用多进程+协程的方法,这样既充分的利用多核的优势,又充分发挥协程的高效率,从而获得高性能。

  4. 协程python的救星!!!

下来我们了解一下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

相关标签: 多任务