python3 asyncio 协程关闭问题,谢谢大家,搞的烦死了~

以下是代码一运行就报错:RuntimeError: Event loop is closed网上找了很多资料的解决方法也都不行,请问哪里的问题?谢谢大家

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import time
import asyncio
import aiohttp

URL = 'https://www.xiazaiba.com'

async def job(session):
    response = await session.get(URL)
    return str(response.url)


async def main(loop):
    async with aiohttp.ClientSession() as session:
        tasks = [loop.create_task(job(session)) for _ in range(5)]
        finished, unfinished = await asyncio.wait(tasks)
        all_results = [r.result() for r in finished]  # 得到工作回报.
        print(all_results)


if __name__ == '__main__':
    t2 = time.time()
    loop = asyncio.get_event_loop()  # 创建一个事件循环对象loop
    try:
        loop.run_until_complete(main(loop))  # 完成事件循环,直到最后一个任务结束
    finally:
        loop.close()  # 结束事件循环.
    print("Async total time:", time.time() - t2)
张雷
Jason990420
最佳答案

try this …

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import time
import asyncio
import aiohttp
import selectors

URL = 'https://www.xiazaiba.com'

async def job(session):
    response = await session.get(URL)
    return str(response.url)


async def main(loop):
    async with aiohttp.ClientSession() as session:
        tasks = [loop.create_task(job(session)) for _ in range(5)]
        finished, unfinished = await asyncio.wait(tasks)
        all_results = [r.result() for r in finished]  # 得到工作回报.
        print(all_results)


if __name__ == '__main__':
    t2 = time.time()
    # loop = asyncio.get_event_loop()           # Removed
    selector = selectors.SelectSelector()       # New line
    loop = asyncio.SelectorEventLoop(selector)  # New line
    try:
        loop.run_until_complete(main(loop))  # 完成事件循环,直到最后一个任务结束
    finally:
        loop.close()  # 结束事件循环.
    print("Async total time:", time.time() - t2)
4年前 评论
讨论数量: 18
Jason990420
>>> loop = asyncio.get_event_loop()
>>> print(loop.is_closed())
True

一般来说这结果都是True, 也就是说 loop 是结束的

loop.run_until_complete(main(loop))

loop.run_until_complete 一开始就发现 loop closed, raise RuntimeError(‘Event loop is closed’)

什么都没作, 马上结束返回.

# loop = asyncio.get_event_loop()
loop = asyncio.new_event_loop()

修改如上, 就 OK 了 !

4年前 评论
张雷

@Jason990420 我按照你说的改了一样会报RuntimeError: Event loop is closed

协程方法

t2 = time.time()
loop = asyncio.new_event_loop()
#loop = asyncio.get_event_loop()  # 创建一个事件循环对象loop
try:
    loop.run_until_complete(main(loop))  # 完成事件循环,直到最后一个任务结束
finally:
    loop.close()  # 结束事件循环.
print("Async total time:", time.time() - t2)
4年前 评论
Jason990420

奇怪了, 我这OK, 你再加一行看是 True 还是 False

    loop = asyncio.new_event_loop()  # 创建一个事件循环对象loop
    print(loop.is_closed())
4年前 评论
Jason990420

试试...

import time
import asyncio
import aiohttp

URL = 'https://www.xiazaiba.com'

async def job(session):
    response = await session.get(URL)
    return str(response.url)

async def main():
    loop = asyncio.get_running_loop()
    async with aiohttp.ClientSession() as session:
        tasks = [loop.create_task(job(session)) for _ in range(5)]
        finished, unfinished = await asyncio.wait(tasks)
        all_results = [r.result() for r in finished]
        print(all_results)

now = time.time()
asyncio.run(main())
print("Async total time:", time.time() - now)
4年前 评论
张雷

@Jason990420 直接拷贝你的代码,还是这样~win10 1909+python3.8.2正式版. file

4年前 评论
张雷

要崩溃了~ :joy:

4年前 评论
张雷

@Jason990420 我这is返回都是False

4年前 评论
张雷

我在MacOS下运行你的代码就正常.........但在win上就不行,都是python3.8.2奇怪咋回事呢这个.

4年前 评论
张雷

我自己的代码什么都不改在MacOS 10.15.4最新版系统上也正常,Mac上python也是3.8.2我要崩溃了.

4年前 评论
Jason990420

我原本是3.7.6, 改为3.8.2, 也出问题了, 一樣是
RuntimeError: Event loop is closed

你原本的代码除出错外, 有先出现那5个网址吗? 我跑你的原代码出错的是

>>> loop = asyncio.get_event_loop()
RuntimeError: There is no current event loop in thread 'MainThread'.
4年前 评论
张雷

@Jason990420 非常感谢,为我排错还特意升级了版本,再次感谢,您所说的问题.

我用我自己的代码,会先出5个普通方法的返回,然后会出现一个列表就是携程后的结果,然后出现一大批RuntimeError: Event loop is closed

截图如下

file

4年前 评论
Jason990420

try this …

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import time
import asyncio
import aiohttp
import selectors

URL = 'https://www.xiazaiba.com'

async def job(session):
    response = await session.get(URL)
    return str(response.url)


async def main(loop):
    async with aiohttp.ClientSession() as session:
        tasks = [loop.create_task(job(session)) for _ in range(5)]
        finished, unfinished = await asyncio.wait(tasks)
        all_results = [r.result() for r in finished]  # 得到工作回报.
        print(all_results)


if __name__ == '__main__':
    t2 = time.time()
    # loop = asyncio.get_event_loop()           # Removed
    selector = selectors.SelectSelector()       # New line
    loop = asyncio.SelectorEventLoop(selector)  # New line
    try:
        loop.run_until_complete(main(loop))  # 完成事件循环,直到最后一个任务结束
    finally:
        loop.close()  # 结束事件循环.
    print("Async total time:", time.time() - t2)
4年前 评论
张雷

我仔细看了下,我自己的代码都是RuntimeError: Event loop is closed没有RuntimeError: There is no current event loop in thread 'MainThread'.

4年前 评论
张雷

@Jason990420 非常感谢您的解答,请问为什么3.76没有问题,Mac也没问题,您换了跟我一样的3.8.2会出现这样的问题?问题在哪里?是python3.8.2的Bug吗?谢谢~

4年前 评论
Jason990420

上面的代码 3.8.2 OK 吗?

4年前 评论
张雷

@Jason990420 OK了,请教下这是什么问题导致啊?

4年前 评论
Jason990420

Platform Support

The asyncio module is designed to be portable, but some platforms have subtle differences and limitations due to the platforms’ underlying architecture and capabilities.

** Changed in version 3.8: On Windows, ProactorEventLoop is now the default event loop. **

All event loops on Windows do not support the following methods:

loop.create_unix_connection() and loop.create_unix_server() are not supported. The socket.AF_UNIX socket family is specific to Unix.

loop.add_signal_handler() and loop.remove_signal_handler() are not supported.

ProactorEventLoop has the following limitations:

The loop.add_reader() and loop.add_writer() methods are not supported.

4年前 评论
张雷

@Jason990420 再次感谢

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!