Message219450
The documentation for the “subprocess” module says that a “with” statement will “wait for” the process, implying that it does not leave a zombie. However this is not the case if there is buffered input data:
$ python3 -Wall -bt -q
>>> import subprocess
>>> with subprocess.Popen(("true",), stdin=subprocess.PIPE, bufsize=-1) as p:
... from time import sleep; sleep(1) # Wait for pipe to be broken
... p.stdin.write(b"buffered data")
...
13
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
File "/usr/lib/python3.4/subprocess.py", line 899, in __exit__
self.stdin.close()
BrokenPipeError: [Errno 32] Broken pipe
>>> # (Hit Ctrl-Z here)
[1]+ Stopped python3 -Wall -bt -q
[Exit 148]
$ ps
PID TTY TIME CMD
15867 pts/5 00:00:00 python3
15869 pts/5 00:00:00 true <defunct>
15873 pts/5 00:00:00 ps
32227 pts/5 00:00:10 bash
Similarly, calling Popen.communicate() does not clean the process up either if there is buffered input data and the process has already exited. The documentation does not spell out how a broken pipe is handled in communicate(), but after reading Issue 10963 I see that in many other cases it is meant to be ignored.
The best way to clean up a subprocess that I have come up with to close the pipe(s) and call wait() in two separate steps, such as:
try:
proc.stdin.close()
except BrokenPipeError:
pass
proc.wait() |
|
Date |
User |
Action |
Args |
2014-05-31 12:57:05 | martin.panter | set | recipients:
+ martin.panter |
2014-05-31 12:57:05 | martin.panter | set | messageid: <1401541025.39.0.6743321007.issue21619@psf.upfronthosting.co.za> |
2014-05-31 12:57:05 | martin.panter | link | issue21619 messages |
2014-05-31 12:57:02 | martin.panter | create | |
|