RuntimeError solve error when running multi-threaded async: There is no current event loop in thread 'Thread-2'

The original use:

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)

  

After you add the following:
    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()

  Root cause in the source code:

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

  

In the main thread, call get_event_loop always returns objects belonging to the main event loop thread, if it is in a non-main thread, you also need to specify a method call set_event_loop event loop objects, such get_event_loop will get to the event loop of the object is marked:


The official document: https://docs.python.org/3/library/asyncio-eventloop.html
I only interception of some of the specific details of the above used go to the official https://docs.python.org/3/library/asyncio-eventloop.html
 

Event Loop

Source:  Lib / ASYNCIO / events.py Lib / ASYNCIO / base_events.py


Foreword

Asynchronous event loop is the heart of every application. Event loop running asynchronous tasks and callbacks, perform network IO operation and run sub-processes.

Application developers should generally use advanced asynchronous functions (e.g.) , and require little or cyclic object references call its methods. This section is intended for the need to better control the event loop behavior of lower level code, authors of libraries and frameworks.asyncio.run()

Get event loop

The following low-level functions can be used to get, set, or create an event loop:

asyncio. get_running_loop

Return to run the event loop current OS thread.

If no event loop is running, it will lead to a. This function can only be called from coroutine or callback.RuntimeError

New features in version 3.7.

asyncio. get_event_loop

Get the current event loop. If the current OS thread does not set the current event loop and has not been called, then asyncio it will create a new event loop and set it to the current event loop.set_event_loop()

Because this function has a rather complex behavior (especially when using a custom event loop strategy), so  the coroutine and callback preferred to use this  function .get_running_loop()get_event_loop()

You can also consider using this function instead of lower-level functions to manually create and close the event loop.asyncio.run()

asyncio. set_event_loop ( Loop )

The loop setting cycle for the current event of the current OS thread.

asyncio. new_event_loop

Create a new event loop object.

Note that behavior , and functions can be changed by  setting a custom event loop policy .get_event_loop()set_event_loop()new_event_loop()

 

 asyncio official document addresses https://docs.python.org/3/library/asyncio.html

Guess you like

Origin www.cnblogs.com/SunshineKimi/p/12053914.html