多个goroutine同时打印到stdout是否安全?

huangapple go评论75阅读模式
英文:

Is it safe for more than one goroutine to print to stdout?

问题

我在我的程序中有多个goroutine,每个goroutine都调用fmt.Println而没有任何显式的同步。这样安全吗(即每行都会单独显示而没有数据损坏),还是我需要创建另一个具有同步功能的goroutine来处理打印?

英文:

I have multiple goroutines in my program, each of which makes calls to fmt.Println without any explicit synchronization. Is this safe (i.e., will each line appear separately without data corruption), or do I need to create another goroutine with synchronization specifically to handle printing?

答案1

得分: 28

不,即使有时候你可能观察不到任何问题,但它仍然不安全。我记得,fmt包试图保持安全,所以可能会发生某种混合,但希望不会导致进程崩溃。

这是Go文档规则的一个实例:除非另有说明或从上下文中明显,否则事物对并发访问不安全。

通过使用log包进行一些小的初始设置,可以获得fmt.Print*功能的安全版本。

英文:

No it's not safe even though you may not sometimes observe any troubles. IIRC, the fmt package tries to be on the safe side, so probably intermixing of some sort may occur but no process crash, hopefully.

This is an instance of a more universal Go documentation rule: Things are not safe for concurrent access unless specified otherwise or where obvious from context.

One can have a safe version of a nice subset of fmt.Print* functionality using the log package with some small initial setup.

答案2

得分: 18

一切fmt所做的都会回退到w.Write(),可以在这里看到。因为它周围没有锁定,所以一切都回退到Write()的实现。由于仍然没有锁定(至少对于Stdout),无法保证输出不会混合。

我建议使用全局日志例程。

此外,如果您只想记录数据,请使用log包,它会正确地锁定对输出的访问。请参考实现

英文:

Everything fmt does falls back to w.Write() as can be seen here. Because there's no locking around it, everything falls back to the implementation of Write(). As there is still no locking (for Stdout at least), there is no guarantee your output will not be mixed.

I'd recommend using a global log routine.

Furthermore, if you simply want to log data, use the log package, which locks access to the output properly.
See the implementation for reference.

答案3

得分: 12

常见的方法(fmt.printLine)是不安全的。然而,有一些方法是安全的。

log.Logger是“goroutine安全”的:https://golang.org/pkg/log/#Logger

像这样创建一个可以安全地从任何go例程中使用的stdout日志记录器。

logger := log.New(os.Stdout, "", 0)

英文:

The common methods (fmt.printLine) are not safe. However, there are methods that are.

log.Logger is "goroutine safe": https://golang.org/pkg/log/#Logger

Something like this will create a stdout logger that can be used from any go routine safely.

logger := log.New(os.Stdout, "", 0)

huangapple
  • 本文由 发表于 2013年2月5日 03:31:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/14694088.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定