我不熟悉这种语言所以请耐心等待。
我很好奇GO如何处理线程可用的数据存储,因为非局部变量也可以是非易失性的,例如在Java中。
GO具有通道的概念,通过它的本质 - 线程间通信,意味着它绕过处理器高速缓存,并直接读取/写入堆。另外,在go lang文档中没有找到对volatile的任何引用。
答案 0 :(得分:12)
TL; DR :Go没有关键字使多个goroutine可以安全地写入/读取变量。使用sync/atomic
包。或者更好的是Do not communicate by sharing memory; instead, share memory by communicating。
Go Memory Model的一些摘录。
如果另一个goroutine必须观察到goroutine的影响, 使用锁或通道等同步机制 建立相对排序的沟通。
Incorrect Synchronization部分中的一个示例是繁忙等待值的示例。
更糟糕的是,无法保证写入已完成 由main观察,因为之间没有同步事件 两个线程。主要的循环不能保证完成。
确实,这段代码(play.golang.org/p/K8ndH7DUzq)永远不会退出。
Go的内存模型没有提供一种解决非标准内存的方法。如果您具有对设备的I / O总线的原始访问权限,则需要使用程序集或C来安全地将值写入内存位置。我只需要在设备驱动程序中执行此操作,这通常会阻止使用Go。
答案 1 :(得分:5)
简单的答案是当前Go规范不支持volatile。
如果您确实有一个需要使用volatile的用例,例如标准库中existing packages不支持的低级原子内存访问,或者硬件映射的无缓冲访问内存,你需要链接在C或汇编文件中。
请注意,如果您使用GC编译器套件所理解的C或程序集,那么您甚至不需要cgo,因为[568] c C / asm编译器也能够处理它。
您可以在Go的源代码中找到相关示例。例如:
许多其他实例的Grep。
有关Go中的内存访问如何工作,请查看The Go Memory Model。
答案 2 :(得分:3)
不,go不支持volatile或register语句。
有关详细信息,请参阅this post。 这也在Go for C++ Programmers guide中注明。
答案 3 :(得分:3)
Go Memory Model文档解释了为什么'volatile'的概念在Go中没有应用。
松散地:除此之外,goroutines可以自由地将goroutine-local更改缓存在寄存器中,以便其他goroutines无法观察到这些更改。要将这些更改“刷新”到内存中,必须执行同步。通过使用锁或通信(通道发送或接收)。