is it a good idea to run the asyncio eventloop inside a thread?
import asyncio
import time
from sample_threading import parallel
loop = asyncio.new_event_loop()
async def fn(p):
for i in range(5):
print(i)
time.sleep(5)
print("done")
@parallel
def th(p):
loop.run_until_complete(fn(p))
th(1)
th(2)
th(3)
above code giving error
raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running
any suggestion ?
You can do that, but you have to explicitly start the event loop inside one - and only one - thread. I do not know the sample_threading.parallel decorator by heart, but I suppose it is automatically creating one thread for each call of your function?
In this case, when the second call is executed, the function runs in the second worker-thread, and tries to reuse the same loop you got a reference to in the global scope. It will work for the first worker thread, since the loop is not yet running, but will fail when you try it again.
Simply create one event loop for each thread you will have.
I am not sure if having the threads created in an implicit and invisible way with this helper lib will make for a more maintainable project. (It already made the understanding of this initial problem harder, for example) - using the traditional threading.Thread() and thread.start() calls, with hard references to the running worker threads will likely be a better choice.
Other than that, just call asyncop.new_event_loop() in a function that runs inside your target worker threads, not on the global scope, and you should be good:
import asyncio
import time
import threading
async def fn(p):
for i in range(5):
print(i)
time.sleep(5)
print("done")
def thread_driver(p):
loop = asyncio.new_event_loop()
loop.run_until_complete(fn(p))
threads = [threading.Thread(target=thread_driver, args=(i,)) for i in range(1,4)]
[t.start() for t in threads()]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With