协程

协程

python的线程用的是操作系统原生的线程

协程:单线程下实现并发

​ 并发:切换+保存状态

​ 多线程:操作系统帮你实现的,如果遇到io切换,执行时间过长也会切换,实现一个雨露均沾的效果.

什么样的协程是有意义的?

遇到io切换的时候才有意义

具体:

​ 协程概念本质是程序员抽象出来的,操作系统根本不知道协程存在,也就说来了一个线程我自己遇到io 我自己线程内部直接切到自己的别的任务上了,操作系统跟本发现不了,也就是实现了单线程下效率最高.

优点:

​ 自己控制切换要比操作系统切换快的多

缺点:

​ 对比多线程

​ 自己要检测所有的io,但凡有一个阻塞整体都跟着阻塞

​ 对比多进程

​ 无法利用多核优势

为什么要有协程(遇到io切换)?

​ 自己控制切换要比操作系统切换快的多.降低了单个线程的io时间

#简单举例
import time
def eat():
    print('eat 1')
    # 疯狂的计算呢没有io
    time.sleep(2)
    # for i in range(100000000):
    #     i+1
def play():
    print('play 1')
    # 疯狂的计算呢没有io
    time.sleep(3)
    # for i in range(100000000):
    #     i+1
play()
eat() # 5s
#通过yield实现协程
import time
def func1():
    while True:
        1000000+1
        yield

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

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

### 对比通过yeild切换运行的时间反而比串行更消耗时间,这样实现的携程是没有意义的。
import time

def func1():
    for i in range(100000000):
        i+1
def func2():
    for i in range(100000000):
        i+1

start = time.time()
func1()
func2()
stop = time.time()
print(stop - start) # 17.141255140304565

Gevent介绍

Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

由于gevent.sleep模拟的是gevent可识别的io阻塞,而time.sleep()或其他的阻塞,gevent是不能直接识别的需要用下面一行代码,打补丁,就可以识别了

from gevent import monkey;monkey.patch_all()放到文件的开头

from gevent import monkey;monkey.patch_all()
import time
import gevent
def eat():
    print('eat 1')
    time.sleep(2)
    print('eat 2')
def play():
    print('play 1')
    # 疯狂的计算呢没有io
    time.sleep(3)
    print('play 2')

start=time.time()
g1=gevent.spawn(eat)
g2=gevent.spawn(play)
g1.join()
g2.join()
end=time.time()
print(end-start)#3.010573148727417
上一篇:python 同步与异步的性能区别以及遇到IO阻塞时会自动切换任务


下一篇:python – map()和imap()如何在gevent.pool.Pool中工作?