Nick Coghlan <ncogh...@gmail.com> added the comment:

Perhaps we need a threading.throw() API, similar to the one we have for 
generators and coroutines?

If we had that, then Py_FinalizeEx() could gain a few new features:

* throw SystemExit into all daemon threads and then give them a chance to 
terminate before calling any atexit handlers (printing a warning if some of the 
threads don't exit)
* throw SystemExit into all daemon and non-daemon threads after running atexit 
handlers (printing a warning if any such threads exist at all, along with 
another warning if some of the threads don't exit)

Adding that would require an enhancement to the PendingCall machinery, though, 
since most pending calls are only processed in the main thread (there's no way 
to route them to specific child threads).

A simpler alternative would be to have an atomic "terminate_threads" counter in 
the ceval runtime state that was incremented to 1 to request that SystemExit be 
raised in daemon threads, and then to 2 to request that SystemExit be raised in 
all still running threads. When a thread received that request to exit, it 
would set a new flag in the thread state to indicate it was terminating, and 
then raise SystemExit. (The thread running Py_FinalizeEx would set that flag in 
advance so it wasn't affected, and other threads would use it to ensure they 
only raised SystemExit once). The runtime cost of this would just be another 
_Py_atomic_load_relaxed call in the eval_breaker branch. (Probably inside 
`make_pending_calls`, so it gets triggered both by the eval_breaker logic, and 
by explicit calls to `Py_MakePendingCalls`).

----------

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

Reply via email to