Skip to content
Advertisement

Asyncio : how to kill a thread in ThreadPoolExecutor by an other coroutine

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.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement