Reputation: 13672
I have a chain of three processes: Process A calls B to spawn C, then B dies. We can call B a "bridge" between two systems A and C.
I want to make sure that C DOES NOT inherit any file descriptors that A opens in order to prevent zombying, which I am currently observing (sometimes A calls B to kill C, and after this, I am seeing defunct C processes hanging around, but I don't know what the code in A looks like).
To make sure this issue isn't due to stdin/out/err being passed down, I am currently doing the following in B
def _close_fds(): #workaround carstens bug
for fd in [0, 1, 2]:
try:
os.close(fd)
except Exception:
logger.info("File descriptor was not open")
...
_close_fds() #make sure there are no open file descriptors for the chile to enherit
pid = subprocess.Popen([_ROOT_PATH + "something.py"]).pid
...
Is there a better way to do this?
Upvotes: 0
Views: 87
Reputation: 43533
When you are starting process C from B, and you don't want it to inherit any file handles, use the following arguments in subprocess.Popen
;
close_fds=True
stdin
, stdout
and stderr
to subprocess.PIPE
or subprocess.DEVNULL
.The first closes all file handles except stdin, stdout and stderr. The arguments listed under (2) take care of those.
Upvotes: 3
Reputation: 50220
The os
module provides a nice function, os.closerange()
, that will do this for you in one call:
os.closerange(0, 3)
If you're hunting after phantom open files, I would go a little higher just in case:
os.closerange(0, 10)
To find out what you actually need to close, you can check /proc/self/fd
for a list of the file descriptors that your process has open (if your OS supports it), and/or use the open_files()
method from psutil. See the answers to this question for even more ideas.
Upvotes: 1