协程是线程中更小的单位:
一、可以通过greenlet实现协程的调度
from greenlet import greenlet
def test1():
print ("12")
t2.switch()
print ("34")
t2.switch()
def test2():
print ("56")
t1.switch()
print ("78")
if __name__=="__main__":
t1 = greenlet(test1) #启动协程
t2 = greenlet(test2) #启动协程
t1.switch()
二、gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中主要用到的是greenlet,它是以c扩展模块模式接入python的
轻量协程,greenlet全部运行在主程序操作的内部,但它们被协程式调用(greenlet是手动切换、gevent是自动切换)。
import gevent
def bar1():
print ("The bar is begin!")
gevent.sleep(3)
print("The bar is end!")
def bar2():
print ("The bar2 is begin!")
gevent.sleep(2)
print ("The bar2 is end!")
def bar3():
print ("The bar3 is begin!")
gevent.sleep(1)
print ("The bar3 is end!")
gevent.joinall([
gevent.spawn(bar1),
gevent.spawn(bar2),
gevent.spawn(bar3)
])
三、协程实现简单的爬虫操作;
from urllib import request
import time,gevent
from gevent import monkey
monkey.patch_all() #把当前的所有io操作打上标记;
def f(url):
print("Get:%s",url)
resp = request.urlopen(url)
data = resp.read()
print("%d bytes receive from %s." % (len(data),url))
urls = [
"https://www.python.org/",
"https://www.yahoo.com/",
"https://www.github.com/"
]
time_start = time.time()
for url in urls: #同步串行;
f(url)
print ("同步cost:",time.time() - time_start)
async_time_start = time.time()
gevent.joinall([ #异常并行;
gevent.spawn(f,"https://www.python.org/"),
gevent.spawn(f,"https://www.yahoo.com/"),
gevent.spawn(f,"https://www.github.com/"),
])
print ("异步cost:",time.time() - async_time_start)