Closed amitmurthy closed 9 years ago
"block" as in "write as a single block"
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?
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.
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.
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.
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.
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.
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.
No way; I don't want to have to use that lock stuff just to break some output into two print calls.
Is the third post in #12600 a related issue?
@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.
@amitmurthy no I meant the output format: the output "0" is between the print "x:1" and "x:2, x:3".
I also get a lot of interleaved printing between Julia and Jupyer in my notebooks.
@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
As folks start working with more parallel constructs, it will be good to have print/println do a block write of the final string.
The newline is written separately.