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)