I have a code like that :
import asyncio import time # long blocking synchronous calls def long_blocking_sync_calls(): print('task 2 (thread) : sleeping for a long time') time.sleep(1000) print('task 2 (thread) : terminate') # task2, that execute blocking_sync_calls in separate thread async def task2(): print('task 2 : running a long blocking call, in a separate thread') loop = asyncio.get_event_loop() await loop.run_in_executor(None, long_blocking_sync_calls) # task1 async def task1(task_2): print('task 1 : waiting') await asyncio.sleep(2) print('task 1 : cancelling task 2 ..') print(str(task_2.cancel())) print('task 1 : task 2 cancelled.') # create tasks and gather async def run(): print('creating tasks..') task_2 = asyncio.create_task(task2()) task_1 = asyncio.create_task(task1(task_2)) print('tasks created. now gather..') await asyncio.gather( task_1, task_2, ) print('program end') if __name__ == '__main__': asyncio.run(run())
The output is as follow :
creating tasks.. tasks created. now gather.. task 2 : running a long blocking call, in a separate thread task 2 (thread) : sleeping for a long time task 1 : waiting task 1 : cancelling task 2 .. True task 1 : task 2 cancelled. ... the program never end here ...
As you can see, I have multiples coroutines that I gather on.
The task2
coroutine is particular, because it executes long blocking calls
(which are not async) in a separate thread.
The problem is that, when the task1
try to cancel task2
, it doesn’t work.
Question : is there a way to kill the long_blocking_sync_calls
thread, from the coroutine task1
?
Thank you
Advertisement
Answer
I end up to a full asyncio
solution, by avoiding any long blocking synchronous calls, thanks to various libraries.