我刚刚观察并确认 Go 闭包通过引用捕获外部变量。如果变量被捕获到一个 Goroutine 中,并且如果 Goroutine 多路复用到不同的线程中,
- 修改闭包中的值安全吗?
- 如果它不安全,为什么 Go 不阻止它?
- 或者它是否采用了某种安全机制? (比如锁)
最佳答案
正如您所注意到的,Go 确实通过闭包中的引用来捕获外部变量。
修改闭包中的值安全吗?
它和其他任何变量一样是一个变量,因此适用与普通 Go 代码中相同的规则。修改它是安全的,但如果您同时修改它,那么您需要提供自己的锁定或使用原子类型。
参见 The Go Memory model了解全部详情。
如果它不安全,为什么不去阻止它呢?
这与访问 go 例程之间共享的任何其他变量没有什么不同。你可以安全地做,也可以不安全地做 - 如果你愿意,Go 给了你搬起石头砸自己脚的自由!
Go has an excellent race detector虽然它可以发现并发变量访问问题。
或者它是否使用了一些安全机制? (比如锁)
没有。 Go 永远不会为你锁定东西 - 你需要使用 sync package 中提供的原语或遵循 Do not communicate by sharing memory; instead, share memory by communicating 的 Go 哲学,即使用 channel 在 go 例程之间进行对话。
关于thread-safety - Go闭包捕获变量和共享数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19873321/