Is `preexec_fn` ever safe in multi-threaded programs? Under what circumstances?

I understand that using subprocess.Popen(..., preexec_fn=X) makes Popen thread-unsafe, and might deadlock.

Question is, are there any circumstances under which it might be safe to do so in multi-threaded programs? E.g. would passing a C-compiled extension function, one that does not acquire any interpreter locks by itself, be safe?

I’m having issues with controlling process hierarchy. Nix* prctl calls that are of interest to me don’t transfer to children, but are preserved across execve calls. Being able to renice children with lambda: os.nice(...) would also be useful.

Also asked at Stack Overflow because I’m not sure where this would fit.