协程之gevent

https://blog.csdn.net/weixin_45651336/article/details/109152460
pip install gevent

gevent在运行时的具体流程大概就是:
    当一个greenlet遇到IO操作时,比如访问网络/睡眠等待,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。同时也因为只有一个线程在执行,会极大的减少上下文切换的成本。

优势

  1. 代码中调用方便;
  2. 拥有的monkey机制

monkey机制
假设你不愿意修改原来已经写好的python代码,但是又想充分利用gevent机制,那么你就可以用monkey来做到这一点。你所要做的就是在文件开头打一个patch,那么它就会自动替换你原来的thread、socket、time、multiprocessing等代码,全部变成gevent框架。这一切都是由gevent自动完成的。注意这个patch是在所有module都import了之后再打,否则没有效果。

from gevent import monkey
monkey.patch_all()
#猴子补丁一般放在顶部,运行的时候修改原模块
import time
import gevent


def work1():
    for i in range(5):
        print("work1-----------")
        time.sleep(1)
        #默认不识别time.sleep()
        #给gevent模块打补丁,。让识别time.sleep,在不修改程序原代码的情况下\
        #为程序增加新功能
        #打补丁方法是导入monkey模块,from gevent import monkey
        #破解 monkey_patch_all()表示破解所有
        #gevent.sleep(0.5)

def work2():
    for i in range(5):
        print("work2---->")
        time.sleep(1)
        #gevent.sleep(0.5)

if __name__ == '__main__':

    g1=gevent.spawn(work1)
    g2= gevent.spawn(work2)
    g1.join()
    g2.join()

输出
work1-----------
work2---->
work1-----------
work2---->
work1-----------
work2---->
work1-----------
work2---->
work1-----------
work2---->

创建协程对象

gevent.spawn()方法会创建一个新的greenlet协程对象,并运行

import gevent


def f1():
    for i in range(5):
        print('run func: f1, index: %s ' % i)
        gevent.sleep(0)


def f2():
    for i in range(5):
        print('run func: f2, index: %s ' % i)
        gevent.sleep(0)


t1 = gevent.spawn(f1)
t2 = gevent.spawn(f2)
gevent.joinall([t1, t2])

输出:
run func: f1, index: 0 
run func: f2, index: 0 
run func: f1, index: 1 
run func: f2, index: 1 
run func: f1, index: 2 
run func: f2, index: 2 
run func: f1, index: 3 
run func: f2, index: 3 
run func: f1, index: 4 
run func: f2, index: 4 

协程返回数据

# coding:utf8
import requests
import gevent
from gevent import monkey
monkey.patch_all()      # 用于将标准库中大部分阻塞式调用修改为协作式运行


def fetch(url):
    print("get: {}".format(url))
    response = requests.get(url).content
    return url, len(response)


if __name__ == "__main__":
    g_list = list()
    for url in ["https://stackoverflow.com/", "https://www.douban.com", "https://www.github.com"]:
        g = gevent.spawn(fetch, url)
        g_list.append(g)
    gevent.joinall(g_list)
    for g in g_list:
        print(g.value)
posted @ 2022-05-19 11:07  ami_miao  阅读(109)  评论(0)    收藏  举报