我是异步编程新手。我正在做一个小型 POC,我想了解 greenlets 与共享对象的行为方式。我写了这段代码 -
from gevent import monkey, sleep
from gevent import Greenlet
monkey.patch_all(thread=False, socket=False)
class Events:
def __init__(self):
self.num = 0
self.limit = 10
self.bulk_records = []
def start(self, task_number=0):
count = 0
print("Task: %s started" % task_number)
while count != 10:
self.bulk_records.append(task_number)
sleep(0.1)
if len(self.bulk_records) == self.limit:
print("%s, Task %s, outputting list: %s" % (self.num, task_number, self.bulk_records))
self.bulk_records[:] = []
self.num += 1
count += 1
print("Task - %s, count - %s" % (task_number, count))
def run_test():
event = Events()
tasks = [Greenlet.spawn(event.start, i) for i in range(5)]
print("Num tasks - %s" % len(tasks))
[task.run() for task in tasks]
print("End")
if __name__ == '__main__':
run_test()
它给出以下输出:-
Num tasks - 5
Task: 0 started
Task: 1 started
Task: 2 started
Task: 3 started
Task: 4 started
0, Task 0, outputting list: [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
1, Task 0, outputting list: [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
2, Task 0, outputting list: [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
3, Task 0, outputting list: [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
4, Task 0, outputting list: [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
Task - 0, count - 10
Task: 1 started # This is not expected
Task - 1, count - 10
Task - 2, count - 10
Task - 3, count - 10
Task - 4, count - 10
5, Task 1, outputting list: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Task - 1, count - 10
End
Process finished with exit code 0
代码按预期工作,但最后发生了一些奇怪的事情,任务 1 再次启动,相应的函数 start
再次执行。
不确定这是否是有效行为,或者我在代码中缺少什么来阻止 Greenlet
再次启动。
先谢谢了
最佳答案
与线程 API 不同的是,线程 API 需要创建一个线程对象并调用 start()
方法,gevent.spawn
既执行 greenlet 实例化,又调度greenlet 在一次调用中运行。
因此,不需要在 greenlet 对象上调用 run()
(在大多数情况下可能是非常错误的)。
等待任务完成是通过joinall(list of greenlets)
完成的。在此调用之后,所有 greenlet 都已准备就绪(死亡、成功或失败)。
关于python - 使用 gevent Greenlets 时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45605606/