eventlet 如何保证任务都运行完了,才退出进程?

from eventlet import monkey_patch
monkey_patch()

import eventlet
import time
from loguru import logger


def run(task_id: int):
    logger.debug(f'开始执行任务: {task_id}')
    time.sleep(3)
    logger.debug(f'开始执行任务: {task_id}')


eventlet.spawn_n(run,1)
eventlet.spawn_n(run,2)

写了上面的代码,但是有一个问题,就是运行后,程序就退出了,都没有执行 run

所以,如何保证任务都运行完了,才退出进程?


chatGPT 给的方法不行,不能运行

图片.png

╰─➤  time python main.py
Traceback (most recent call last):
  File "/Users/ponponon/Desktop/code/me/ideaboom/main.py", line 18, in <module>
    eventlet.greenthread.waitall()
AttributeError: module 'eventlet.greenthread' has no attribute 'waitall'
python main.py  0.49s user 0.07s system 79% cpu 0.702 total
阅读 2.1k
2 个回答
import eventlet

def run(task_id):
    print(f'开始执行任务: {task_id}')
    eventlet.sleep(3)
    print(f'结束执行任务: {task_id}')

pool = eventlet.greenpool.GreenPool()
pool.spawn_n(run, 1)
pool.spawn_n(run, 2)
pool.waitall() # 等待所有协程执行完毕


print('所有任务已完成')

官方api给到了函数的说明,spawn_n 是快速执行,没有返回值的,所以它不知道什么时候你所调用的func程序会执行结束。

eventlet.spawn_n(func, args, *kw)

The same as spawn(), but it’s not possible to know how the function terminated (i.e. no return value or exceptions). This makes execution faster. See spawn_n for more details.

方案一:你可以使用 eventletEvent 控制。

from eventlet import Event, monkey_patch

monkey_patch()

import time

import eventlet
from loguru import logger

event = Event()


def run(task_id: int):
    logger.debug(f"开始执行任务: {task_id}")
    time.sleep(3)
    logger.debug(f"开始执行任务: {task_id}")
    if event.has_result():
        event.reset()
    event.send(True)


eventlet.spawn_n(run, 1)
eventlet.spawn_n(run, 2)

event.wait()

方案二:你不要使用 spawn_n,转而使用 spawn 方法。

因为 spawn 会返回一个 GreenThread 对象,并且你可以通过这个返回拿到对应 func 的返回值。

eventlet.spawn(func, args, *kw)

This launches a greenthread to call func. Spawning off multiple greenthreads gets work done in parallel. The return value from spawn is a greenthread.GreenThread object, which can be used to retrieve the return value of func. See spawn for more details.
from eventlet import monkey_patch

monkey_patch()

import time

import eventlet
from loguru import logger


def run(task_id: int):
    logger.debug(f"开始执行任务: {task_id}")
    time.sleep(3)
    logger.debug(f"开始执行任务: {task_id}")


res1 = eventlet.spawn(run, 1)
res2 = eventlet.spawn(run, 2)

res1.wait()
res2.wait()

方案三: 使用GreenPool去控制, waitall() 控制所有任务完成后退出

from eventlet import GreenPool, monkey_patch

monkey_patch()

import time

from loguru import logger

pool = GreenPool()


def run(task_id: int):
    logger.debug(f"开始执行任务: {task_id}")
    time.sleep(3)
    logger.debug(f"开始执行任务: {task_id}")


res1 = pool.spawn_n(run, 1)
res2 = pool.spawn_n(run, 2)

pool.waitall()
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题