0.生成器
1.使用yield完成多任务
import time
def task_1():
while True:
print("---1----")
time.sleep(0.1)
yield
def task_2():
while True:
print("---2----")
time.sleep(0.1)
yield
def main():
t1 = task_1()
t2 = task_2()
# 先让t1运行一会,当t1中遇到yield的时候,再返回到24行,然后
# 执行t2,当它遇到yield的时候,再次切换到t1中
# 这样t1/t2/t1/t2的交替运行,最终实现了多任务....协程
while True:
next(t1)
next(t2)
if __name__ == "__main__":
main()
运行结果:
---1----
---2----
---1----
---2----
---1----
---2----
---1----
...
2.使用greenlet完成多任务
from greenlet import greenlet
import time
def test1():
while True:
print("---A--")
gr2.switch()
time.sleep(0.5)
def test2():
while True:
print("---B--")
gr1.switch()
time.sleep(0.5)
#创建生成器对象
gr1 = greenlet(test1)
gr2 = greenlet(test2)
#切换到gr1中运行,开始输出
gr1.switch()
运行结果:
---A--
---B--
---A--
---B--
---A--
....
3.使用gevent完成多任务
import gevent
import time
def f1(n):
for i in range(n):
print(gevent.getcurrent(), i)
# time.sleep(0.5)
gevent.sleep(0.5) #延时、堵塞等操作,都需要换成gevent里边的相应方法
def f2(n):
for i in range(n):
print(gevent.getcurrent(), i)
# time.sleep(0.5)
gevent.sleep(0.5) #延时、堵塞等操作,都需要换成gevent里边的相应方法
def f3(n):
for i in range(n):
print(gevent.getcurrent(), i)
# time.sleep(0.5)
gevent.sleep(0.5) #延时、堵塞等操作,都需要换成gevent里边的相应方法
print("----1---")
g1 = gevent.spawn(f1, 5)
print("----2---")
g2 = gevent.spawn(f2, 5)
print("----3---")
g3 = gevent.spawn(f3, 5)
print("----4---")
g1.join() # 堵塞,等待完成
g2.join() # 堵塞,等待完成
g3.join() # 堵塞,等待完成
运行结果:
----1---
----2---
----3---
----4---
<Greenlet at 0x15bf8f917b8: f1(5)> 0
<Greenlet at 0x15bf8f918c8: f2(5)> 0
<Greenlet at 0x15bf8f919d8: f3(5)> 0
<Greenlet at 0x15bf8f917b8: f1(5)> 1
<Greenlet at 0x15bf8f918c8: f2(5)> 1
<Greenlet at 0x15bf8f919d8: f3(5)> 1
<Greenlet at 0x15bf8f917b8: f1(5)> 2
<Greenlet at 0x15bf8f918c8: f2(5)> 2
<Greenlet at 0x15bf8f919d8: f3(5)> 2
<Greenlet at 0x15bf8f917b8: f1(5)> 3
<Greenlet at 0x15bf8f918c8: f2(5)> 3
<Greenlet at 0x15bf8f919d8: f3(5)> 3
<Greenlet at 0x15bf8f917b8: f1(5)> 4
<Greenlet at 0x15bf8f918c8: f2(5)> 4
<Greenlet at 0x15bf8f919d8: f3(5)> 4
注意,此时使用的延时是gevent.sleep(0.5),若使用time.sleep(0.5),则输出结果如下:
----1---
----2---
----3---
----4---
<Greenlet at 0x2b3ce8917b8: f1(5)> 0
<Greenlet at 0x2b3ce8917b8: f1(5)> 1
<Greenlet at 0x2b3ce8917b8: f1(5)> 2
<Greenlet at 0x2b3ce8917b8: f1(5)> 3
<Greenlet at 0x2b3ce8917b8: f1(5)> 4
<Greenlet at 0x2b3ce8918c8: f2(5)> 0
<Greenlet at 0x2b3ce8918c8: f2(5)> 1
<Greenlet at 0x2b3ce8918c8: f2(5)> 2
<Greenlet at 0x2b3ce8918c8: f2(5)> 3
<Greenlet at 0x2b3ce8918c8: f2(5)> 4
<Greenlet at 0x2b3ce8919d8: f3(5)> 0
<Greenlet at 0x2b3ce8919d8: f3(5)> 1
<Greenlet at 0x2b3ce8919d8: f3(5)> 2
<Greenlet at 0x2b3ce8919d8: f3(5)> 3
<Greenlet at 0x2b3ce8919d8: f3(5)> 4
4.gevent打补丁
有耗时操作时,需要将程序中用到的耗时操作的代码,替换成gevent中自己实现的模块,比如讲time.sleep(0.5)自动替换gevent.sleep(0.5),需要打补丁,方法如下:
首先导入:from gevent import monkey
然后执行:monkey.patch_all()
import gevent
import time
from gevent import monkey
# 有耗时操作时,需要将程序中用到的耗时操作的代码,替换成gevent中自己实现的模块
monkey.patch_all()
def f1(n):
for i in range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5)
def f2(n):
for i in range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5)
def f3(n):
for i in range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5)
print("----1---")
g1 = gevent.spawn(f1, 5)
print("----2---")
g2 = gevent.spawn(f2, 5)
print("----3---")
g3 = gevent.spawn(f3, 5)
print("----4---")
g1.join()
g2.join()
g3.join()