#11778: p_iter_fork doesn't flush stdout properly
------------------------------+---------------------------------------------
Reporter: johanbosman | Owner: tbd
Type: defect | Status: positive_review
Priority: major | Milestone: sage-4.7.2
Component: misc | Keywords: parallel fork stdout
Work_issues: | Upstream: N/A
Reviewer: Leif Leonhardy | Author: Johan Bosman
Merged: | Dependencies:
------------------------------+---------------------------------------------
Description changed by leif:
Old description:
> The following code
> {{{
> from sage.parallel.use_fork import p_iter_fork
>
> def f(n):
> print "Entering f with n=%s" % n
> X = p_iter_fork(1, verbose=True)
> iter_result = X(g, [((n,), {})])
> result = list(iter_result)[0][1]
> print "Leaving f with n=%s" % n
> return result # Which is just n
>
> def g(n):
> print "Inside g with n=%s" % n
> return n
>
> def test():
> X = p_iter_fork(2, verbose=True)
> inputs = [((n,), {}) for n in range(5)]
> iter_result = X(f, inputs)
> for n in iter_result:
> pass
>
> test()
> }}}
> gives this output (perhaps in a different order):
> {{{
> Entering f with n=1
> Entering f with n=1
> Inside g with n=1
> Leaving f with n=1
> Entering f with n=0
> Entering f with n=0
> Inside g with n=0
> Leaving f with n=0
> Entering f with n=2
> Entering f with n=2
> Inside g with n=2
> Leaving f with n=2
> Entering f with n=3
> Entering f with n=3
> Inside g with n=3
> Leaving f with n=3
> Entering f with n=4
> Entering f with n=4
> Inside g with n=4
> Leaving f with n=4
> }}}
> The point is that stdout isn't flushed before the process is forked and
> therefore its contents are copied to the child process as well and thus
> lives in 2 processes.
New description:
The following code
{{{
from sage.parallel.use_fork import p_iter_fork
def f(n):
print "Entering f with n=%s" % n
X = p_iter_fork(1, verbose=True)
iter_result = X(g, [((n,), {})])
result = list(iter_result)[0][1]
print "Leaving f with n=%s" % n
return result # Which is just n
def g(n):
print "Inside g with n=%s" % n
return n
def test():
X = p_iter_fork(2, verbose=True)
inputs = [((n,), {}) for n in range(5)]
iter_result = X(f, inputs)
for n in iter_result:
pass
test()
}}}
gives this output (perhaps in a different order):
{{{
Entering f with n=1
Entering f with n=1
Inside g with n=1
Leaving f with n=1
Entering f with n=0
Entering f with n=0
Inside g with n=0
Leaving f with n=0
Entering f with n=2
Entering f with n=2
Inside g with n=2
Leaving f with n=2
Entering f with n=3
Entering f with n=3
Inside g with n=3
Leaving f with n=3
Entering f with n=4
Entering f with n=4
Inside g with n=4
Leaving f with n=4
}}}
The point is that stdout isn't flushed before the process is forked and
therefore its contents are copied to the child process as well and thus
lives in 2 processes.
----
Apply
1. [attachment:11778_flush_before_fork.patch]
1. [attachment:trac_11778-flush_output_of_print_stmts.reviewer.patch]
to the Sage library.
--
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/11778#comment:18>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.