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