首页 > 技术文章 > python3 协程gevent模块(遇到IO自动切换)

lilyxiaoyy 2019-06-16 23:21 原文

协程
在一个线程中并发执行多个任务,当遇到IO操作的时候,自动切换到其他任务去执行。

  gevent 是第三方的一个模块,需要手动安装pip install gevent

先看一个例子
from gevent import monkey
monkey.patch_all()  # 记住一定放在第一行,这里是打补丁的意思,time模块在使用协程gevent模块的时候,必须打补丁才行,记得放在第一行。
import gevent
import time


def eat(name):
    print(f"{name} eat first")
    time.sleep(3)
    print(f"{name} eat second")


def play(name):
    print(f"{name} play phone 1")
    time.sleep(2)
    print(f"{name} play phone 2")


g1 = gevent.spawn(eat, "lily")
g2 = gevent.spawn(play, name="lily")
g1.join()
g2.join()

执行结果:

lily eat first
lily play phone 1
lily play phone 2
lily eat second
协程之间数据是安全的,因为同一时间只能有一个协程在执行。


接下来看下协程能干什么?先看一个正常爬取多个网页源代码的例子(爬取网页
import time
import requests


def get_page(url):
    response = requests.get(url)
    print(url)
    if response.status_code == 200:
        print(response.text)


start_time = time.time()
get_page("https://www.python.org")
get_page("https://www.yahoo.com")
get_page("https://github.com")
print("执行时间:%s" % (time.time()-start_time))

执行结果:

执行时间:4.218241214752197

 

再看一个使用了协程后的时间(使用gevent模块爬取网页

from gevent import monkey;monkey.patch_all()
import gevent
import time
import requests


def get_page(url):
    response = requests.get(url)
    print(url)
    if response.status_code == 200:
        print(response.text)


start_time = time.time()
g1 = gevent.spawn(get_page, "https://www.python.org")
g2 = gevent.spawn(get_page, "https://www.yahoo.com")
g3 = gevent.spawn(get_page, "https://github.com")
gevent.joinall([g1, g2, g3])
print("执行时间:%s" % (time.time()-start_time))

执行结果:

执行时间:2.399137496948242

明显比上面不使用协程的程序快多了。

推荐阅读