greenlet实现协程
greenlet+switch机制来实现协程
greenlet用于创建协程,switch用于进行协程之间的切换某个协程在执行的过程中可以随时的被其他协程通过switch函数来打断,转而去执行其他协程,当前协程的中断现场会被保留,一旦中断的协程再次获得cpu的执行权首先会恢复现场然后从中断处继续执行
这种机制下的协程是同步,不能并发
from greenlet import greenlet
from time import sleep
def func1():
print("协程1")
sleep(2)
g2.switch()
print("协程1恢复运行")
def func2():
print("协程2")
sleep(1)
g3.switch()
def func3():
print("协程3")
sleep(1)
g1.switch()
if __name__ == '__main__':
# 使用greenlet来创建三个协程
g1 = greenlet(func1)
g2 = greenlet(func2)
g3 = greenlet(func3)
# print(g1)
g1.switch() # 让协程g1取抢占cpu资源
'''
协程1
协程2
协程3
协程1恢复运行
'''
gevent创建协程
import gevent
from time import sleep
def func1():
print("协程1")
sleep(2)
def func2():
print("协程2")
sleep(1)
def func3():
print("协程3")
if __name__ == '__main__':
# 用gevent来创建三个协程
g1 = gevent.spawn(func1)
g2 = gevent.spawn(func2)
g3 = gevent.spawn(func3)
# 将三个协程加入同步对列中
gevent.joinall([g1,g2,g3])
# gevent+同步对列机制
# 通过gevent创建协程,然后把协程加入到同步队列中,就可以头同步执行
'''
协程1
协程2
协程3
'''
gevent+monkey
# 协程被创建出来以后默认是多个协程同步执行
# 我们可以加入monkey补丁,把同步的协程转成异步协程
from gevent import monkey #注意:monkey的引入必须在其他模块之前
monkey.patch_all() # 用monkey给整个协程队列,添加一个非阻塞I/O的补丁,使得他们成为异步协程
import requests
import gevent
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
def func(url,i):
print("协程%d开启!"%i)
res = requests.get(url=url,headers=headers)
html = res.text
print("协程%d执行结束,获取到的响应体大小为:%d"%(i,len(html)))
if __name__ == '__main__':
urls = [
"https://www.baidu.com/",
"https://www.qq.com/",
"https://www.sina.com.cn",
"https://www.ifeng.com/",
"https://www.163.com/"
]
# 创建5个协程分别对上面5个网站进行访问
g_list = []
for i in range(len(urls)):
g = gevent.spawn(func,urls[i],i)
g_list.append(g)
gevent.joinall(g_list)
'''
协程0开启!
协程1开启!
协程2开启!
协程3开启!
协程4开启!
协程0执行结束,获取到的响应体大小为:156719
协程4执行结束,获取到的响应体大小为:675831
协程3执行结束,获取到的响应体大小为:218003
协程2执行结束,获取到的响应体大小为:579035
协程1执行结束,获取到的响应体大小为:232192
'''