協程
在一個線程中並發執行多個任務,當遇到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
明顯比上面不使用協程的程序快多了。
