Message151808
> I also found that under Python 2.x, even a low-level exit like
> os._exit or multiprocessing.win32.ExitProcess, called from within a
> user-level function in the child, caused flushing.
The difference is the following:
- Python 2.x uses C stdio (write() calls C fwrite(), flush() calls C
fflush(), etc.); buffering is managed by the libc and what you see at
shutdown is the behaviour of your platform's libc
- Python 3.x uses its own buffering mechanism; it flushes automatically
when the object destructor is called, but os._exit() bypasses all
destructors
Now why os._exit() is used. The problem with sys.exit() is that it's too
high-level: it merely raises a SystemExit exception. That exception can
be caught by upper levels in the code stack. When you use fork() and you
are in the child process, you don't want to give back control to the
calling function, especially if that function isn't fork()-aware (think
about what happens if that function writes to a file, both in the child
and the parent).
This happens for example when running multiprocessing's own test suite:
if forking.py used sys.exit(), the child's SystemExit exception would be
caught by the unittest framework, be interpreted as a test failure, and
the rest of the test suite would proceed... in both processes!
It is less obvious, however, why ExitProcess is used under Windows.
Windows doesn't use fork(), it launches a separate process from scratch.
Perhaps for "consistency" with the Unix behaviour.
> 2. Add an explicit stdout/stderr flush where appropriate in
> forking.py and process.py, to ensure tracebacks get written and to
> match the unix behavior. Leave it to the user to worry about flushing
> their own streams.
That's the simplest solution, and the least likely to break
compatibility with user code. |
|
Date |
User |
Action |
Args |
2012-01-23 11:10:53 | pitrou | set | recipients:
+ pitrou, jnoller, brandjon |
2012-01-23 11:10:52 | pitrou | link | issue13812 messages |
2012-01-23 11:10:51 | pitrou | create | |
|