Issue
I have written the following code:
import asyncio
import time
from threading import Thread
from threading import Timer
async def myCouroutine():
time.sleep(3)
dbAccessLoop = None
def stopEventLoop():
dbAccessLoop.stop()
def eventLoopThreadMain():
global dbAccessLoop
try:
dbAccessLoop = asyncio.new_event_loop()
dbAccessLoop.run_forever()
finally:
dbAccessLoop.close()
def main():
thread = Thread(target = eventLoopThreadMain)
thread.start()
stopLoopTimer = Timer(3, stopEventLoop)
stopLoopTimer.start()
while dbAccessLoop is not None and dbAccessLoop.is_running():
dbAccessLoop.call_soon_threadsafe(asyncio.ensure_future, myCouroutine())
break
thread.join()
if __name__ == '__main__':
main()
The program creates new event loop, starts it, runs coroutine (doing some work) and then after some time using timer it stops the loop. I expect that after calling stop() method dbAccessLoop.run_forever() will give execution back, but that is not happening.
Do I missed something here? My guess is that stop() method is not thread safe but I do not see any errors in the console. Thanks in advance.
Solution
There seems to be a hole at least in the setting of the dbAccessLoop
.
main -> thread: start
main -> while: dbAccessLoop is None => bailout
thread -> dbAccessLoop = whatever
Also, https://docs.python.org/3/library/asyncio-dev.html#detect-never-awaited-coroutines tells me that the coroutine myCoroutine
might not be scheduled. But that's another problem.
And apart from that, indeed "Almost all asyncio objects are not thread safe, which is typically not a problem unless there is code that works with them from outside of a Task or a callback." (https://docs.python.org/3/library/asyncio-dev.html#asyncio-multithreading), so the code should call the stop
in the eventloop's thread using dbAccessLoop.call_soon_threadsafe(dbAccessLoop.stop)
.
Answered By - xtofl
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.