协程

作者: knot98 | 来源:发表于2018-09-10 19:10 被阅读0次

协程:是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是协程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。

1. 目标:

在线程下实现并发
    并发(多个任务看起来是同时执行就是并发):切换+保存状态

2. 协程:

协程是单线程实现并发
注意:协程是程序员意淫出来的东西,操作系统里只有进程和线程的概念(操作系统调度的是线程)

在单线程下实现多个任务间遇到IO就切换就可以降低单线程的IO时间,从而最大限度地提升单线程的效率

总结协程特点:
1 .在一个单线程里实现并发
2 .修改共享数据不需加锁
3 .用户程序里自己保存多个控制流的上下文栈
附加:一个协程遇到IO操作自动切换到其它协程(如何实现检测IO,yield、greenlet都无法实现,就用到了gevent模块(select机制))

#串行执行
import time

def func1():
    for i in range(10000000):
        i+1

def func2():
    for i in range(10000000):
        i+1

start = time.time()
func1()
func2()
stop = time.time()
print(stop - start)  # 所需时间:1.1090044975280762



#基于yield并发执行
import time
def func1():
    while True:
        yield

def func2():
    g=func1()
    for i in range(10000000):
        i+1
        next(g)

start=time.time()
func2()
stop=time.time()
print(stop-start)  # 所需时间:1.6645479202270508

从上面代码中可以知道在单线程下,如果是计算密集型代码,使用yield并发执行,相对于串行执行并不能提高效率,反而会降低效率.
IO密集型:

#基于yield并发执行
import time
def func1():
    while True:
        print('func1')
        yield

def func2():
    g=func1()
    for i in range(10000000):
        print('func2')
        time.sleep(100)
        i+1
        next(g)

start=time.time()
func2()
stop=time.time()
print(stop-start)

经过测试可以得知yield不会遇到IO就切换,所有说yelid方法pass,进而引出gevent模块

gevent模块

安装gevent模块,在cmd窗口中输入 pip3 install gevent
(前提是安装了python3 并且配置好了环境变量)

from gevent import monkey;monkey.patch_all()
from gevent import spawn,joinall 
import time

def play(name):
    print('%s play 1' %name)
    time.sleep(5)
    print('%s play 2' %name)

def eat(name):
    print('%s eat 1' %name)
    time.sleep(3)
    print('%s eat 2' %name)


start=time.time()
g1=spawn(play,'HGQ')
g2=spawn(eat,'HGQ')

# g1.join()
# g2.join()
joinall([g1,g2])
print('主',time.time()-start)

相关文章

网友评论

      本文标题:协程

      本文链接:https://www.haomeiwen.com/subject/xmhegftx.html