Go语言支持volatile/non-volatile变量吗?

huangapple go评论111阅读模式
英文:

Does Go support volatile / non-volatile variables?

问题

我刚开始学习这门语言,请谅解。

我很好奇GO语言如何处理线程可用的数据存储,就像Java中的非局部变量一样,它们也可以是非易失性的。

GO有通道的概念,通过它进行线程间通信,这意味着它绕过处理器缓存,直接读写堆。

此外,在GO语言的文档中没有找到关于volatile的任何参考。

英文:

I'm new to the language so bear with me.

I am curious how GO handles data storage available to threads, in the sense that non-local variables can also be non-volatile, like in Java for instance.

GO has the concept of channel, which, by it's nature -- inter thread communication, means it bypasses processor cache, and reads/writes to heap directly.

Also, have not found any reference to volatile in the go lang documentation.

答案1

得分: 18

TL;DR: Go语言没有关键字可以使变量在多个goroutine中进行安全的写入/读取。可以使用sync/atomic包来实现。或者更好的做法是不要通过共享内存进行通信,而是通过通信来共享内存


对于volatile的两个含义,有两个答案。
Go语言支持volatile/non-volatile变量吗?

.NET/Java并发

以下是来自Go内存模型的一些摘录。

> 如果一个goroutine的效果必须被另一个goroutine观察到,
> 使用同步机制,如锁或通道通信来建立相对顺序。

不正确的同步部分的一个示例是一个在值上进行忙等待的示例。

> 更糟糕的是,不能保证done的写入会被main观察到,因为两个线程之间没有同步事件。main中的循环不保证会结束。

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

C/C++非标准内存

Go语言的内存模型没有提供一种处理非标准内存的方法。如果你可以直接访问设备的I/O总线,你需要使用汇编语言或C语言来安全地向内存位置写入值。我只在设备驱动程序中需要过这样做,而通常不能使用Go语言。

英文:

TL;DR: Go does not have a keyword to make a variable safe for multiple goroutines to write/read it. Use the sync/atomic package for that. Or better yet Do not communicate by sharing memory; instead, share memory by communicating.


Two answers for the two meanings of volatile
Go语言支持volatile/non-volatile变量吗?

.NET/Java concurrency

Some excerpts from the Go Memory Model.

> If the effects of a goroutine must be observed by another goroutine,
> use a synchronization mechanism such as a lock or channel
> communication to establish a relative ordering.

One of the examples from the Incorrect Synchronization section is an example of busy waiting on value.

> Worse, there is no guarantee that the write to done will ever be
> observed by main, since there are no synchronization events between
> the two threads. The loop in main is not guaranteed to finish.

Indeed, this code(play.golang.org/p/K8ndH7DUzq) never exits.

C/C++ non-standard memory

Go's memory model does not provide a way to address non-standard memory. If you have raw access to a device's I/O bus you'll need to use assembly or C to safely write values to the memory locations. I have only ever needed to do this in a device driver which generally precludes use of Go.

答案2

得分: 5

简单的答案是,当前的Go规范不支持volatile关键字。

如果你确实有使用volatile关键字的情况,比如低级别的原子内存访问,在标准库的现有包中不支持,或者对硬件映射内存进行无缓冲访问,你需要链接一个C或汇编文件。

请注意,如果你使用的是GC编译器套件理解的C或汇编语言,甚至不需要cgo,因为[568]c C/asm编译器也能处理它。

你可以在Go的源代码中找到这方面的示例。例如:

还可以在其他地方搜索相关实例。

关于Go中的内存访问方式,请参考《Go内存模型》。

英文:

The simple answer is that volatile is not supported by the current Go specification, period.

If you do have one of the use cases where volatile is necessary, such as low-level atomic memory access that is unsupported by existing packages in the standard library, or unbuffered access to hardware mapped memory, you'll need to link in a C or assembly file.

Note that if you do use C or assembly as understood by the GC compiler suite, you don't even need cgo for that, since the [568]c C/asm compilers are also able to handle it.

You can find examples of that in Go's source code. For example:

Grep for many other instances.

For how memory access in Go does work, check out The Go Memory Model.

答案3

得分: 4

不,Go语言不支持volatile或register语句。

更多信息请参考这篇帖子
这也在Go for C++ Programmers指南中有说明。

英文:

No, go does not support the volatile or register statement.

See this post for more information.
This is also noted in the Go for C++ Programmers guide.

答案4

得分: 4

《Go内存模型》文档解释了为什么在Go语言中没有应用“volatile”这个概念。

简单来说,除其他事项外,goroutine可以自由地将goroutine本地的更改缓存在寄存器中,这样其他goroutine就无法观察到这些更改。要将这些更改“刷新”到内存中,必须执行同步操作。可以通过使用锁或通过通信(通道发送或接收)来实现同步。

英文:

The Go Memory Model documentation explains why the concept of 'volatile' has no application in Go.

Loosely: Among other things, goroutines are free to keep goroutine-local changes cached in registers so those changes are not observable by other goroutines. To "flush" those changes to memory, a synchronization must be performed. Either by using locks or by communicating (channel send or receive).

huangapple
  • 本文由 发表于 2013年8月28日 22:38:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/18491032.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定