zoukankan      html  css  js  c++  java
  • 解决async 运行多线程时报错RuntimeError: There is no current event loop in thread 'Thread-2'

    原来使用:

    loop = asyncio.get_event_loop()
    task = asyncio.ensure_future(do_work(checker))
    loop.run_until_complete(asyncio.wait([task]))
    st = task.result()
    修改后使用:
    添加了
        new_loop = asyncio.new_event_loop()
        asyncio.set_event_loop(new_loop)
    

      

    添加后如下:
        new_loop = asyncio.new_event_loop()
        asyncio.set_event_loop(new_loop)
        loop = asyncio.get_event_loop()
        task = asyncio.ensure_future(do_work(checker))
        loop.run_until_complete(asyncio.wait([task]))
        st = task.result()
    

      根本原因在源码中:

    def get_event_loop(self):
        """Get the event loop.
        This may be None or an instance of EventLoop.
        """
        if (self._local._loop is None and
                not self._local._set_called and
                isinstance(threading.current_thread(), threading._MainThread)):
            self.set_event_loop(self.new_event_loop())
    
        if self._local._loop is None:
            raise RuntimeError('There is no current event loop in thread %r.'
                                % threading.current_thread().name)
    
        return self._local._loop
    

      

    在主线程中,调用get_event_loop总能返回属于主线程的event loop对象,如果是处于非主线程中,还需要调用set_event_loop方法指定一个event loop对象,这样get_event_loop才会获取到被标记的event loop对象:


    官方文档:https://docs.python.org/3/library/asyncio-eventloop.html
    我只截取上述用到的部分具体详情请前往官方https://docs.python.org/3/library/asyncio-eventloop.html
     

    事件循环

    源代码: Lib / asyncio / events.py, Lib / asyncio / base_events.py


    前言

    事件循环是每个异步应用程序的核心。事件循环运行异步任务和回调,执行网络IO操作并运行子流程。

    应用程序开发人员通常应使用高级异步函数(例如)asyncio.run(),并且几乎不需要引用循环对象或调用其方法。本部分主要面向需要更好地控制事件循环行为的较低级代码,库和框架的作者。

    获取事件循环

    以下低级函数可用于获取,设置或创建事件循环:

    asyncio.get_running_loop

    返回当前OS线程中的运行事件循环。

    如果没有正在运行的事件循环,RuntimeError则会引发一个。只能从协程或回调中调用此函数。

    3.7版中的新功能。

    asyncio.get_event_loop

    获取当前事件循环。如果当前OS线程set_event_loop()中没有设置当前事件循环并且尚未调用,那么asyncio将创建一个新的事件循环并将其设置为当前事件循环。

    因为此函数具有相当复杂的行为(尤其是在使用自定义事件循环策略时),所以 在协程和回调中get_running_loop()首选使用此 函数get_event_loop()

    还可以考虑使用该asyncio.run()函数,而不要使用较低级别的函数来手动创建和关闭事件循环。

    asyncio.set_event_loop循环

    loop设置为当前OS线程的当前事件循环。

    asyncio.new_event_loop

    创建一个新的事件循环对象。

    需要注意的是行为get_event_loop()set_event_loop()new_event_loop()功能都可以通过改变 设置自定义事件循环政策

     asyncio 官方文档地址https://docs.python.org/3/library/asyncio.html

  • 相关阅读:
    Chrome 控制台console的用法[转]
    Page Visibility(页面可见性) API介绍、微拓展[转]
    移动端rem单位用法[转]
    JavaScript继承方式详解[转]
    说说React
    Flex 布局教程:语法篇[转]
    git 常用命令总结
    Supervisor 在ubuntu系统下添加自启动
    Django 通过APNS推送消息
    通过 python-xmp-toolkit 读取图片xmlp信息
  • 原文地址:https://www.cnblogs.com/SunshineKimi/p/12053914.html
Copyright © 2011-2022 走看看