使用 gevent Greenlets 时的奇怪行为
Weird behavior while using gevent Greenlets
我是异步编程的新手。我正在做一个小的 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
重新开始。
提前致谢
与需要创建线程对象并调用start()
方法的线程API相反,gevent.spawn
既进行greenlet实例化又将greenlet调度到运行 一通电话。
因此,不需要在 greenlet 对象上调用 run()
(在大多数情况下可能是非常错误的)。
等待任务完成是用 joinall(list of greenlets)
完成的。在这个调用之后,所有的 greenlets 都准备好了(死了,成功与否)。
我是异步编程的新手。我正在做一个小的 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
重新开始。
提前致谢
与需要创建线程对象并调用start()
方法的线程API相反,gevent.spawn
既进行greenlet实例化又将greenlet调度到运行 一通电话。
因此,不需要在 greenlet 对象上调用 run()
(在大多数情况下可能是非常错误的)。
等待任务完成是用 joinall(list of greenlets)
完成的。在这个调用之后,所有的 greenlets 都准备好了(死了,成功与否)。