diff options
author | Jesse Noller <jnoller@gmail.com> | 2009-06-30 17:11:52 (GMT) |
---|---|---|
committer | Jesse Noller <jnoller@gmail.com> | 2009-06-30 17:11:52 (GMT) |
commit | 1b90efbdc5bb204fe50aea87374603dcba309227 (patch) | |
tree | 42a36dca54321c6caf5e9ca488bdc1be1988b9d2 /Doc/library/multiprocessing.rst | |
parent | 0c9eb431491387fc68940e2b24dc873f3147e0c8 (diff) | |
download | cpython-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.rst | 32 |
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 ~~~~~~~ |