New submission from Ben Darnell <ben.darn...@gmail.com>:

I'm dealing with a subtle deadlock involving 
concurrent.futures.ThreadPoolExecutor, and my solution that worked in Python 
3.8 broke with 3.9. I'm running some long-running (possibly infinite) tasks in 
the thread pool, and I cancel them in an `atexit` callback so that everything 
can shut down cleanly (before ThreadPoolExecutor joins all worker threads in 
its own `atexit` hook).

Python 3.9 broke this due to https://bugs.python.org/issue39812. That change 
introduced a new atexit-like mechanism to the threading module and uses it 
where Python 3.8 used regular atexit. This means that ThreadPoolExecutor's 
atexit runs before mine, and since I never get a chance to cancel my tasks, it 
deadlocks.

One way I can solve this is to move my own atexit function to 
`threading._register_atexit`, so my strawman proposal here is to make that 
function public and documented. 

On the other hand, even without the change in Python 3.9, my use of `atexit` 
smells like an abuse of implementation details in ThreadPoolExecutor (getting 
the atexit callbacks called in the right order was tricky when the 
concurrent.futures module started using lazy loading in Python 3.7). So I would 
welcome other suggestions about how to handle long-running but cancelable 
operations in a ThreadPoolExecutor at shutdown. 

One clean solution is to do the cancellation at the end of the main module 
instead of in an atexit hook. However, I'm doing this at a library so I don't 
have any way but atexit to ensure that this happens. Another option is to 
forego ThreadPoolExecutor entirely and manage the threads myself. 

My code in question is in a not-yet-released branch of Tornado: 
https://github.com/tornadoweb/tornado/blob/5913aa43ecfdaa76876fc57867062227b907b1dd/tornado/platform/asyncio.py#L57-L73

With the master branch of Tornado, Python 3.9, and Windows, `python -c "from 
tornado.httpclient import HTTPClient; c = HTTPClient()` reliably deadlocks at 
interpreter shutdown.

----------
messages: 378144
nosy: Ben.Darnell
priority: normal
severity: normal
status: open
title: Make threading._register_atexit public?
versions: Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue41962>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to