summaryrefslogtreecommitdiffstats
path: root/Doc/library/multiprocessing.rst
diff options
context:
space:
mode:
authorJesse Noller <jnoller@gmail.com>2009-06-30 17:11:52 (GMT)
committerJesse Noller <jnoller@gmail.com>2009-06-30 17:11:52 (GMT)
commit1b90efbdc5bb204fe50aea87374603dcba309227 (patch)
tree42a36dca54321c6caf5e9ca488bdc1be1988b9d2 /Doc/library/multiprocessing.rst
parent0c9eb431491387fc68940e2b24dc873f3147e0c8 (diff)
downloadcpython-1b90efbdc5bb204fe50aea87374603dcba309227.zip
cpython-1b90efbdc5bb204fe50aea87374603dcba309227.tar.gz
cpython-1b90efbdc5bb204fe50aea87374603dcba309227.tar.bz2
Resolves issues 5155, 5313, 5331 - bad file descriptor error with processes in processes
Diffstat (limited to 'Doc/library/multiprocessing.rst')
-rw-r--r--Doc/library/multiprocessing.rst32
1 files changed, 32 insertions, 0 deletions
diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst
index 7aaa8e3..04828bb 100644
--- a/Doc/library/multiprocessing.rst
+++ b/Doc/library/multiprocessing.rst
@@ -2101,6 +2101,38 @@ Explicitly pass resources to child processes
for i in range(10):
Process(target=f, args=(lock,)).start()
+Beware replacing sys.stdin with a "file like object"
+
+ :mod:`multiprocessing` originally unconditionally called::
+
+ os.close(sys.stdin.fileno())
+
+ In the :meth:`multiprocessing.Process._bootstrap` method of - this resulted
+ in issues with processes-in-processes. This has been changed to::
+
+ sys.stdin.close()
+ sys.stdin = open(os.devnull)
+
+ Which solves the fundamental issue of processes colliding with each other
+ resulting in a bad file descriptor error, but introduces a potential danger
+ to applications which replace :func:`sys.stdin` with a "file-like object"
+ with output buffering, this danger is that if multiple processes call
+ :func:`close()` on this file-like object, it could result in the same
+ data being flushed to the object multiple times, resulting in corruption.
+
+ If you write a file-like object and implement your own caching, you can
+ make it fork-safe by storing the pid whenever you append to the cache,
+ and discarding the cache when the pid changes. For example::
+
+ @property
+ def cache(self):
+ pid = os.getpid()
+ if pid != self._pid:
+ self._pid = pid
+ self._cache = []
+ return self._cache
+
+ For more information, see :issue:`5155`, :issue:`5313` and :issue:`5331`
Windows
~~~~~~~