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

时间:2013-08-28 14:38:47

标签: go

我不熟悉这种语言所以请耐心等待。

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

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

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

4 个答案:

答案 0 :(得分:12)

TL; DR :Go没有关键字使多个goroutine可以安全地写入/读取变量。使用sync/atomic包。或者更好的是Do not communicate by sharing memory; instead, share memory by communicating


two meanings of volatile的两个答案 volatile Ven diagram

.NET / Java 并发

Go Memory Model的一些摘录。

  

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

Incorrect Synchronization部分中的一个示例是繁忙等待值的示例。

  

更糟糕的是,无法保证写入已完成   由main观察,因为之间没有同步事件   两个线程。主要的循环不能保证完成。

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

C / C ++ 非标准内存

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无法观察到这些更改。要将这些更改“刷新”到内存中,必须执行同步。通过使用锁或通信(通道发送或接收)。