我刚刚观察并确认 Go 闭包通过引用捕获外部变量。如果变量被捕获到 Goroutine 中并且 Goroutine 多路复用到不同的线程中,
- 修改闭包中的值是否安全?
- 如果它不安全,为什么 Go 不阻止呢?
- 或者它是否采用了某种安全机制?(如锁)
我刚刚观察并确认 Go 闭包通过引用捕获外部变量。如果变量被捕获到 Goroutine 中并且 Goroutine 多路复用到不同的线程中,
正如您所注意到的,Go 确实通过在闭包中的引用来捕获外部变量。
修改闭包中的值是否安全?
它和其他任何变量一样都是一个变量,因此适用的规则与普通 Go 代码中的规则相同。修改它是安全的,但如果您同时修改它,那么您需要提供自己的锁定或使用原子类型。
有关完整详细信息,请参阅Go Memory 模型。
如果不安全,为什么不去阻止呢?
这与访问 go 例程之间共享的任何其他变量没有什么不同。您可以安全地进行操作,也可以不安全地进行操作 - 如果您愿意,Go 让您可以自由地在脚上开枪!
Go 有一个出色的竞争检测器,虽然它可以发现并发变量访问问题。
或者它是否使用了一些安全机制?(如锁)
不,Go 永远不会为你锁定东西——你需要使用同步包中提供的原语或遵循 Go 的理念,即不要通过共享内存进行通信;相反,通过通信共享内存,即使用通道在 go 例程之间进行对话。