Skip to content

print/println should block write final output #3787

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
amitmurthy opened this issue Jul 22, 2013 · 15 comments · Fixed by #10521 or #12978
Closed

print/println should block write final output #3787

amitmurthy opened this issue Jul 22, 2013 · 15 comments · Fixed by #10521 or #12978
Milestone

Comments

@amitmurthy
Copy link
Contributor

As folks start working with more parallel constructs, it will be good to have print/println do a block write of the final string.

julia> @sync begin
           for i in 1:3
               @async begin
                   println("Getting garbled")
               end
           end
       end
Getting garbledGetting garbledGetting garbled



The newline is written separately.

julia> @sync begin
           for i in 1:3
               @async begin
                   println(`Getting garbled`)
               end
           end
       end
```GGGeeettttttiiinnnggg   gggaaarrrbbbllleeeddd```

@amitmurthy
Copy link
Contributor Author

"block" as in "write as a single block"

@JeffBezanson
Copy link
Member

This behavior doesn't seem so great. It's easy to write a string and a newline in a single operation, but we don't want to have to worry about that sort of thing all the time. Maybe some sort of buffering is the answer? @loladiro
Or use buffering for files and sockets, and make TTYs nonblocking?

@Keno
Copy link
Member

Keno commented Jul 22, 2013

libuv has the capability to write multiple things at once. It's just that our I/O system doesn't work that way. Making TTY's nonblocking seems fine, since writing to TTYs blocks the whole process anyway.

@JeffBezanson
Copy link
Member

But, we have to arrange for the output to be consistent over the different kinds of streams. It would be bad to get different output when redirecting to a file than when testing by printing to the screen.

@Keno
Copy link
Member

Keno commented Jul 22, 2013

I don't think you can insist on that. In fact in most situations, you can probably not even depend on the output being the same between julia runs.

@StefanKarpinski
Copy link
Member

Line buffering for text streams seems reasonable to me. But of course, we then need a distinction between printing to a text stream and printing to a byte stream, but we've talked about that before already.

@JeffBezanson
Copy link
Member

Maybe we can''t insist on identical output in all sorts of scenarios, but getting the expected output at the prompt and then one of Amit's outputs above in a file seems gratuitous to me. The sensitivity to print("a\n") versus print('a','\n') is also a big pitfall.
Even with nondeterminism, we can still pick a model of what sorts of phenomena are possible. Sure, if several tasks print messages I might get them in any order, but hopefully not interleaved character-by-character.

@vtjnash
Copy link
Member

vtjnash commented Jul 23, 2013

I suspect this is showing up now because we are now doing blocking writes, which presumably means there is a a task switch required by each call to the low-level write function.

Another possibility is to introduce locking:

print(s) = 
    lock(STDOUT) do
        print(STDOUT, text)
    end

function lock(fn, stream)
    lock(stream)
    try
        fn()
    finally
        unlock(stream)
    end
end

Where lock/unlock are the traditional recursive binary semaphores.

I'm not sure exactly where this would be put into the hierarchy of show/print.

@JeffBezanson
Copy link
Member

No way; I don't want to have to use that lock stuff just to break some output into two print calls.

@amitmurthy
Copy link
Contributor Author

Regression in 334a2be

@amitmurthy amitmurthy reopened this Sep 6, 2015
@amitmurthy amitmurthy added this to the 0.4.0 milestone Sep 6, 2015
@Sisyphuss
Copy link

Is the third post in #12600 a related issue?

@amitmurthy
Copy link
Contributor Author

@Sisyphuss , #12600 is not related and not a bug. for introduces a new scope as documented. global x = i will result in the behavior you are looking for.

@Sisyphuss
Copy link

@amitmurthy no I meant the output format: the output "0" is between the print "x:1" and "x:2, x:3".

@KristofferC
Copy link
Member

I also get a lot of interleaved printing between Julia and Jupyer in my notebooks.

@amitmurthy
Copy link
Contributor Author

@KristofferC can you post examples? Currently only println to asynchronous streams is locked. If you are using print statements, you will need to manage it manually - http://docs.julialang.org/en/latest/manual/faq/#asynchronous-io-and-concurrent-synchronous-writes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants