Python 使用gevent Greenlets时的奇怪行为

Python 使用gevent Greenlets时的奇怪行为,python,python-3.x,gevent,greenlets,Python,Python 3.x,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 s

我是异步编程新手。我正在做一个小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相反,它需要创建一个线程对象并调用
start()
方法,
gevent.spawn
执行greenlet实例化并安排greenlet在一次调用中运行

因此,不需要对greenlet对象调用
run()
(在大多数情况下可能是非常错误的)


等待任务完成是通过
joinall(greenlet列表)
完成的。在这次调用之后,所有的greenlet都准备好了(死了,成功了还是没有)。

看了一眼,除了greenlet/gevent中的一个bug之外,我没有任何解释。。。不过,这样一个bug似乎不太可能被发现?您使用的是什么版本的Python?您是否也理解greenlet在调用
print
时会产生问题?这个调用“[task.run()for task in tasks]”是错误的;这是干什么用的<代码>生成已运行greenlet。您希望等待,直到使用
gevent.joinall(任务)
完成greenlet的执行。不要直接打电话给“run”。您好@mguijarr,请将此作为答案发布,我将接受。您提供的解决方案有效。谢谢