Bug 4600 – writeln() is not thread-safe

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
Other
OS
Linux
Creation time
2010-08-08T20:53:00Z
Last change time
2014-03-09T05:47:57Z
Assigned to
nobody
Creator
issues.dlang

Comments

Comment #0 by issues.dlang — 2010-08-08T20:53:43Z
Okay. Maybe I misunderstood something somewhere, but as I understand it, writeln() is supposed to be thread-safe. Multiple threads can interleave lines that they're printing, but each line that a thread prints with writeln() is supposed to be completely printed before a line from another thread can be printed. However, at least some of the time, the output from one thread is mixed with another on the same line. For instance, take this program: import std.concurrency; import std.stdio; void main(string[] args) { spawn(&func1, thisTid, args.idup); spawn(&func2, thisTid, args.idup); writeln("main() 1"); writeln("main() 2"); writeln("main() 3"); } void func1(Tid parentTid, immutable string[] args) { writefln("func1() begin"); writefln("func1(): %s", args); writefln("func1() end"); } void func2(Tid parentTid, immutable string[] args) { writefln("func2() begin"); writefln("func2(): %s", args); writefln("func2() end"); } If I run it like so ./d hello world I get: main() 1 main() 2 main() 3 func1() beginfunc2() begin func1() beginfunc2() begin [./d, hello, world] func2() end or main() 1 func1() beginfunc2() begin main() 2 func1() beginfunc2() begin main() 2 main() 3 eginfunc2() begin main() 3 or in this case, the line printing out the args array doesn't even print the whole beginning of the line: main() 1 main() 2 main() 3 func1() begin func1() begin func2() begin , hello, world] func1() end In some cases, the lines are properly printed (naturally with whole lines potentially interleaved due to the multiple threads running), but often they aren't. So, if writeln() is really supposed to be thread-safe, it's buggy. If it's not, then programs intending to use writeln() (or its sibling write functions) are going to need to wrap them with locks or some other concurrency mechanism to being able to safely print, which certainly wouldn't play well with the whole message-passing for concurrency paradigm.
Comment #1 by beatgammit — 2013-05-22T23:59:00Z
(In reply to comment #0) > Okay. Maybe I misunderstood something somewhere, but as I understand it, > writeln() is supposed to be thread-safe. Multiple threads can interleave lines > that they're printing, but each line that a thread prints with writeln() is > supposed to be completely printed before a line from another thread can be > printed. However, at least some of the time, the output from one thread is > mixed with another on the same line. For instance, take this program: > > import std.concurrency; > import std.stdio; > > void main(string[] args) > { > spawn(&func1, thisTid, args.idup); > spawn(&func2, thisTid, args.idup); > writeln("main() 1"); > writeln("main() 2"); > writeln("main() 3"); > } > > void func1(Tid parentTid, immutable string[] args) > { > writefln("func1() begin"); > writefln("func1(): %s", args); > writefln("func1() end"); > } > > void func2(Tid parentTid, immutable string[] args) > { > writefln("func2() begin"); > writefln("func2(): %s", args); > writefln("func2() end"); > } I couldn't reproduce this with the current DMD. This issue is quite old, so it's possibly invalid now. I'm running Linux x86_64 with DMD 2.062. Also tried ldc2 (targeting DMD 2.061), no problems. Can this be closed?
Comment #2 by stanislav.blinov — 2014-02-10T11:28:27Z
(In reply to comment #1) I'm not seeing this behavior either on Linux x86_64 dmd2.064.2, but I cannot find any specific commits in git history.
Comment #3 by peter.alexander.au — 2014-03-09T05:05:12Z
Jonathan, is this fixed for you now? I cannot repro and neither can previous two comments.
Comment #4 by issues.dlang — 2014-03-09T05:47:57Z
> Jonathan, is this fixed for you now? I cannot repro and neither can previous two comments. Well, I can't repro it now either. I have no idea whether the problem was actually fixed or not, but since several of us can't repro it at this point, we might as well close this as fixed. If someone is later actually able to reproduce it, they can reopen the bug or create a new one.