3 回答
TA贡献1799条经验 获得超9个赞
首先,你需要了解 go memory 模型:
要理解的关键点是,goroutine 中变量写入的影响不一定对另一个 goroutine 可见,就像写入 goroutine 观察它们的方式一样。也就是说,如果一个 goroutine 将一个值写入一个变量a
,然后再写入另一个变量b
,另一个 goroutine 可能会以未指定的顺序看到这些写入。这就是为什么您需要像通道或互斥锁这样的并发原语。在通道操作或互斥操作之前发生的任何事情都将在此时对所有 goroutine 可见。
原子操作提供了类似的保证,尽管内存模型没有明确指定。
使用原子编写代码并不容易。您必须考虑所有可能的执行交错以确保没有竞争。坚持使用通道和互斥锁。正确的代码比快速但活泼的代码要好。
TA贡献2011条经验 获得超2个赞
想象一下,有 5 个 goroutine 同时访问初始化为 0 的同一个内存/源并试图增加它。常规增量“+”操作会导致数据竞争,因为由于同时操作无法保证状态被正确更新。最后,不能保证共享变量的值为 5
在这种情况下,原子操作会有所帮助,因为它们会锁定内存以供 goroutine 进行安全操作,因此不会观察到数据竞争
您还可以使用通道或互斥锁来锁定状态并安全操作,更推荐
TA贡献1831条经验 获得超4个赞
您根本 不应该使用包atomic。
正如包装文档明确指出的那样
包 atomic 提供了用于实现同步算法的低级原子内存原语。
这些功能需要非常小心才能正确使用。除了特殊的低级应用程序外,最好使用通道或同步包的工具来完成同步。通过通信共享内存;不要通过共享内存进行通信。
它仅供专家使用。
你问:“'=' 和 '+' 不是异常的吗?” 不!Go 中没有任何东西(!)是原子的,除了包 atomic 中的原语(因此得名)、包同步提供的内容和通道操作。
所以不,您不能同时使用=
, +
, -
,/
等。而且你真的不应该编写假设某些东西是原子的就是正确的代码。始终提供正确的同步(通过包同步)或通过渠道。
- 3 回答
- 0 关注
- 138 浏览
添加回答
举报