It seems on python>=3.4 subprocess.Popen(..., stdin=PIPE, stdout=PIPE, close_fds=False)
is a possible option. This is due to a patch that makes all opened file descriptors non-inheritable by default. To be more precise, they will be automatically closed on execv
(so still can't use multiprocessing.Process
), see PEP 446.
This is also a valid option for other python versions:
- on windows, HANDLEs are created non-inheritable by default, so you will leak only handles that were made inheritable explicitly
- on POSIX/python<=3.3 you can still use os.closerange to close open file descriptors after spawning the subprocess
for a corresponding example see:
https://github.com/coldfix/python-ipc-test
The most useful combinations are:
stdio:pickle
- pro: completely cross-platform in my tests
- pro: fastest option (with 2)
- con: stdin/stdout can not be redirected independently
inherit_unidir:pickle
- pro: you can redirect STDIO streams independently
- pro: fastest option together with stdio:pickle
- con: very low level platform specific code
socket:sockpipe
- pro: cross-platform with little effort
- con: there is a short period when "attackers" may connect to the port, you could require a pass-phrase or something to prevent that from happening
- con: slightly slower than alternatives on windows (factor 1.6 in my measurements)
- when not using AF_UNIX there are unpredictable performance hits on linux