Skip to content

Commit 3a2611f

Browse files
committed
Add description of the deadlock problem with child processes and pipes, and
hints about how to work around it. Closes SF bug #530637.
1 parent 4a84870 commit 3a2611f

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

Doc/lib/libos.tex

+5
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,11 @@ \subsection{File Object Creation \label{os-newstreams}}
314314
objects should be opened in binary or text mode. The default value
315315
for \var{mode} is \code{'t'}.
316316

317+
For a discussion of possible dead lock conditions related to the use
318+
of these functions, see ``\ulink{Flow Control
319+
Issues}{popen2-flow-control.html}''
320+
(section~\ref{popen2-flow-control}).
321+
317322
\begin{funcdesc}{popen2}{cmd\optional{, mode\optional{, bufsize}}}
318323
Executes \var{cmd} as a sub-process. Returns the file objects
319324
\code{(\var{child_stdin}, \var{child_stdout})}.

Doc/lib/libpopen2.tex

+62
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,65 @@ \subsection{Popen3 and Popen4 Objects \label{popen3-objects}}
107107
\begin{memberdesc}{pid}
108108
The process ID of the child process.
109109
\end{memberdesc}
110+
111+
112+
\subsection{Flow Control Issues \label{popen2-flow-control}}
113+
114+
Any time you are working with any form of inter-process communication,
115+
control flow needs to be carefully thought out. This remains the case
116+
with the file objects provided by this module (or the \refmodule{os}
117+
module equivalents).
118+
119+
% Example explanation and suggested work-arounds substantially stolen
120+
% from Martin von Löwis:
121+
% http://mail.python.org/pipermail/python-dev/2000-September/009460.html
122+
123+
When reading output from a child process that writes a lot of data to
124+
standard error while the parent is reading from the child's standard
125+
out, a dead lock can occur. A similar situation can occur with other
126+
combinations of reads and writes. The essential factors are that more
127+
than \constant{_PC_PIPE_BUF} bites are being written by one process in
128+
a blocking fashion, while the other process is reading from the other
129+
process, also in a blocking fashion.
130+
131+
There are several ways to deal with this situation.
132+
133+
The simplest application change, in many cases, will be to follow this
134+
model in the parent process:
135+
136+
\begin{verbatim}
137+
import popen2
138+
139+
r, w, e = popen2.popen3('python slave.py')
140+
e.readlines()
141+
r.readlines()
142+
r.close()
143+
e.close()
144+
w.close()
145+
\end{verbatim}
146+
147+
with code like this in the child:
148+
149+
\begin{verbatim}
150+
import os
151+
import sys
152+
153+
# note that each of these print statements
154+
# writes a single long string
155+
156+
print >>sys.stderr, 400 * 'this is a test\n'
157+
os.close(sys.stderr.fileno())
158+
print >>sys.stdout, 400 * 'this is another test\n'
159+
\end{verbatim}
160+
161+
In particular, note that \code{sys.stderr} must be closed after
162+
writing all data, or \method{readlines()} won't return. Also note
163+
that \function{os.close()} must be used, as \code{sys.stderr.close()}
164+
won't close \code{stderr} (otherwise assigning to \code{sys.stderr}
165+
will silently close it, so no further errors can be printed).
166+
167+
Applications which need to support a more general approach should
168+
integrate I/O over pipes with their \function{select()} loops, or use
169+
separate threads to read each of the individual files provided by
170+
whichever \function{popen*()} function or \class{Popen*} class was
171+
used.

0 commit comments

Comments
 (0)