为什么需要loop.run_forever?

来源:13-3 task取消和子协程调用原理

荒小七

2020-07-05

import asyncio
import time

async def get_html(sleep_times):
    print("waiting")
    await asyncio.sleep(sleep_times)
    print("done after {}s".format(sleep_times))


if __name__ == "__main__":
    task1 = get_html(2)
    task2 = get_html(3)
    task3 = get_html(3)

    tasks = [task1, task2, task3]

    loop = asyncio.get_event_loop()

    try:
        loop.run_until_complete(asyncio.wait(tasks))
    except KeyboardInterrupt as e:
        pass
        all_tasks = asyncio.Task.all_tasks()
        for task in all_tasks:
            print("cancel task")
            print(task.cancel())
        loop.stop()
        loop.run_forever()
    finally:
        loop.close()

老师,在您的代码中我有些不理解这个loop.stop()和loop.run_forever()。
我是这么想的,在代码运行的时候Ctrl+C终止代码会导致事件循环终止,直接进入到异常处理中,但是您在异常处理中又使用了loop.stop(),意思是Ctrl+C并不会终止事件循环是吗?后面的那个loop.run_forever()就更加不能理解了,在这里写一句这个岂不是和while True一样,一直在这里循环,怎么会去执行finally中的代码呢?感觉有点不可思议,还有就是那个Task was destroyed but it is pending!这个错误的原因我也没有排查出来,为什么会出现这个错误呢?

写回答

1回答

bobby

2020-07-05

ctrl+c和直接进程中杀死进程不一样的, ctrl+C一般情况下这个关闭信息程序可以捕捉, 也就是说如果你捕捉到了这个信号 然后再这个信号处理事件中你什么都不做 那么你的程序就无法被ctrl+c终止。如果你是强杀进程这个处理方式你的代码是无法捕捉到的 所以一般程序都会处理ctrl+c信号 来做优雅退出处理

0
2
bobby
回复
荒小七
能具体说明一下视频哪个时间点提到了这个吗 之前的版本好像有这个问题 不过好像新的版本中不需要这样做了
2020-07-07
共2条回复

Python3高级核心技术97讲,高级进阶的必学课程

socket编程/多线程/多进程/线程池/asyncio并发编程/协程和异步IO

2121 学习 · 551 问题

查看课程