python - 使用 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
        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/

相关文章:

python - 为帐户指定的 FieldError : Unknown field(s) (created_at, Modified_at)

python - 线程不足 : UWSGI + Multithreaded Python Application with GeventHTTPClient

python - Celery worker 收到任务但没有执行

python - 如何在python中将数组保存到文本文件?

python - 预创建多线程 Python 应用程序

python - 使用 nohup 时更改 python 版本

python - 在同一单元格中绘制图

python - 如何在Python中使用 `issubset`作为字典

Python 多处理问题?

python - 如何简化这些字典理解?