Go是否支持易失/非易失性变量?

Rau*_*aul 17 go

我是这个语言的新手,所以请耐心等待.

我很好奇GO如何处理线程可用的数据存储,因为非局部变量也可以是非易失性的,例如在Java中.

GO具有通道的概念,通过它的本质 - 线程间通信,意味着它绕过处理器高速缓存,并直接读取/写入堆.

另外,在go lang文档中没有找到对volatile的任何引用.

def*_*ode 12

TL; DR:Go没有关键字使多个goroutine可以安全地写入/读取变量.使用sync/atomic包.或者更好的是不要通过共享内存进行通信; 相反,通过沟通分享记忆.


两个含义的两个答案volatile 挥发性Ven图

.NET/Java 并发

Go Memory Model的一些摘录.

如果必须由另一个goroutine观察到goroutine的影响,请使用锁定或通道通信等同步机制来建立相对排序.

" 不正确的同步"部分中的一个示例是忙等待值的示例.

更糟糕的是,由于两个线程之间没有同步事件,所以不能保证main会观察到写入完成.main中的循环无法保证完成.

实际上,这段代码(play.golang.org/p/K8ndH7DUzq)永远不会退出.

C/C++ 非标准内存

Go的内存模型没有提供一种解决非标准内存的方法.如果您具有对设备的I/O总线的原始访问权限,则需要使用程序集或C来安全地将值写入内存位置.我只需要在设备驱动程序中执行此操作,这通常会排除使用Go.

  • 引用的代码没有退出,因为主循环阻止了执行的例程.通过将runtime.GOMAXPROCS增加到2,代码将退出:https://play.golang.org/p/n-sC8jISyw (3认同)

zzz*_*zzz 5

Go内存模型文档解释了为什么“易失性”概念在 Go 中没有应用。

宽松地:除其他外,goroutine 可以自由地将 goroutine 本地更改缓存在寄存器中,因此其他 goroutine 无法观察到这些更改。要将这些更改“刷新”到内存中,必须执行同步。通过使用锁或通过通信(通道发送或接收)。

  • Go 内存模型没有说明为什么不支持 volatile,也没有解释为什么 volatile 在 Go 中没有应用。相反,它解释了它是如何工作的。易失性的存在正是为了标记变量,否则这些变量也会遵循 C 或 C++ 中的不同规则。 (2认同)
  • @Raul:全局的局部变量,内存模型以同样的方式应用。不同步意味着不能保证其他人可以观察到更改。 (2认同)

Gus*_*yer 5

简单的答案是当前Go规范不支持volatile.

如果您确实有一个需要使用volatile的用例,例如标准库中现有 不支持的低级原子内存访问,或者对硬件映射内存的无缓冲访问,则需要链接到C或汇编文件.

请注意,如果您使用GC编译器套件所理解的C或程序集,那么您甚至不需要cgo,因为[568] c C/asm编译器也能够处理它.

您可以在Go的源代码中找到相关示例.例如:

Grep用于许多其他实例.

有关Go中的内存访问如何工作,请查看Go Go Memory Model.


nem*_*emo 4

不,go 不支持 volatile 或 register 语句。

请参阅这篇文章了解更多信息。Go for C++ 程序员指南中也指出了这一点。