You’re right – there is no nice API for this. You’re also right on your second point – it’s trivially easy to design a function that does this for you using threading.
import threading
import subprocess
def popen_and_call(on_exit, popen_args):
"""
Runs the given args in a subprocess.Popen, and then calls the function
on_exit when the subprocess completes.
on_exit is a callable object, and popen_args is a list/tuple of args that
would give to subprocess.Popen.
"""
def run_in_thread(on_exit, popen_args):
proc = subprocess.Popen(*popen_args)
proc.wait()
on_exit()
return
thread = threading.Thread(target=run_in_thread, args=(on_exit, popen_args))
thread.start()
# returns immediately after the thread starts
return thread
Even threading is pretty easy in Python, but note that if on_exit() is computationally expensive, you’ll want to put this in a separate process instead using multiprocessing (so that the GIL doesn’t slow your program down). It’s actually very simple – you can basically just replace all calls to threading.Thread
with multiprocessing.Process
since they follow (almost) the same API.