Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems using asyncio in Thread

There is no problem using asyncio as follows.

import asyncio


async def main():
    await asyncio.sleep(1)
    aaa = 1
    print (aaa)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

However, I have to use asyncio within Thread as shown in the simple code below, which results in an error as follows

import asyncio
import threading

async def main():
    await asyncio.sleep(1)
    aaa = 1
    print (aaa)


def test():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()


t=threading.Thread(target=test)
t.start()

Error Message (RuntimeError: There is no current event loop in thread 'Thread-1'.)

Exception in thread Thread-1:
Traceback (most recent call last):
  File "D:\Anaconda3\Lib\threading.py", line 932, in _bootstrap_inner
    self.run()
  File "D:\Anaconda3\Lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "D:/Test/Test4/main.py", line 57, in test
    loop = asyncio.get_event_loop()
  File "D:\Anaconda3\Lib\asyncio\events.py", line 639, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.

How can I use asyncio in Thread?

This is very important to me. I've been struggling with this problem for two days.

I would appreciate your help.

like image 381
hscho070 hscho070 Avatar asked Aug 27 '26 10:08

hscho070 hscho070


2 Answers

Unless you need to work with a pre-existing event loop (not the case here) or support Python 3.6, use asyncio.run instead of manually handling the loop:

def test():
    asyncio.run(main())

This always ensures that there is a valid event loop, and also handles proper cleanup.

This function always creates a new event loop and closes it at the end. It should be used as a main entry point for asyncio programs, and should ideally only be called once.


Note that when combining asyncio with threads, the event loop should generally be run in the main loop (see e.g. bpo#34697). Instead of spawning a thread for asyncio, prefer to spawn one for the synchronous parts of your program.

# launch synchronous work in child threads
t=threading.Thread(target=my_sync_tasks)
t.start()

# launch asynchronous work in main thread
asyncio.run(main())
t.join()

When using a thread other than the main thread you need to set the event loop

def test():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(main())
    loop.close()
like image 28
Guy Avatar answered Aug 30 '26 00:08

Guy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!