#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.

Reply via email to