python使用gevent实现协程

gevent是一个基于协程的python网络库,在遇到IO阻塞时,程序会自动进行切换,可以让我们用同步的方式写异步IO代码。

# 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
    print("{}: {}".format(url, len(response)))


if __name__ == "__main__":
    gevent.joinall([
        gevent.spawn(fetch, "https://stackoverflow.com/"),
        gevent.spawn(fetch, "https://www.douban.com"),
        gevent.spawn(fetch, "https://www.github.com")
    ])

结果为:

>>> get: https://stackoverflow.com/
>>> get: https://www.douban.com
>>> get: https://www.github.com
>>> https://www.douban.com: 94054
>>> https://www.github.com: 87186
>>> https://stackoverflow.com/: 261295

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

gevent.joinall()方法的参数是一个协程对象列表,它会等待所有的协程都执行完毕后再退出

 

如果想获取协程返回的数据,可以这样做:

# 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)

结果为:

>>> get: https://stackoverflow.com/
>>> get: https://www.douban.com
>>> get: https://www.github.com
>>> ('https://stackoverflow.com/', 260097)
>>> ('https://www.douban.com', 94050)
>>> ('https://www.github.com', 87180)

 

posted @ 2019-05-25 21:38  永恒de记忆  阅读(11187)  评论(0编辑  收藏  举报