go - 解释: Don't communicate by sharing memory; share memory by communicating

标签 go memory channel goroutine

我想知道对这句名言最接地气的解释是什么:

Don't communicate by sharing memory; share memory by communicating. (R. Pike)

The Go Memory Model我可以读到这个:

A send on a channel happens before the corresponding receive from that channel completes. (Golang Spec)

还有一个专用的golang article解释报价。关键贡献是 working example也由 Andrew G.

嗯。有时谈论太多了....我从 Memory Spec 引文中得出,并通过查看工作示例得出:

After a goroutine1 sends (anything) to a goroutine2 via a channel, then all changes (anywhere in the memory) done by goroutine1 must be visible to goroutine2 after it received via same channel. (Golang Lemma by Me:)

因此,我得出这句名言的脚踏实地的解释:

To synchronize memory access between two goroutines, you don't need to send that memory via channel. Good enough is to receive from the channel (even nothing). You will see any changes that were written (anywhere) by the goroutine sending (to the channel) at the time of it's send. (Of course, assuming no other goroutines are writing to the same memory.) Update (2) 8-26-2017

其实我有两个问题:

1) 我的结论正确吗?

2) 我的解释有帮助吗?

更新(1) 我假设 无缓冲 channel 。让我们先把自己限制在这一点上,以避免用太多的未知数来彻底检查自己。

请让我们也关注一个简​​单的用例,即两个 goroutine 通过单个 channel 进行通信以及相关的内存效应,而不是最佳实践——这超出了这个问题的范围。

为了更好地理解我的问题的范围,假设 goroutine 可以访问任何类型的内存结构 - 不仅是原始的 - 它可以是一个大的,它可以是一个字符串、映射、数组等等。

最佳答案

这句名言如果过于乱七八糟,可能会有点令人困惑。让我们将其分解为更基本的组件,并正确定义它们:

Don't communicate by sharing memory; share memory by communicating
      ---- 1 ----    ------ 2 -----  ---- 3 -----    ----- 4 -----
  1. 这意味着不同的执行线程将通过读取将在其他地方修改的内存来通知其他线程的状态变化。 POSIX 共享内存 API:http://man7.org/linux/man-pages/man7/shm_overview.7.html 就是一个完美的例子(尽管是针对进程而不是线程)。 . 这种技术需要适当的同步,因为数据竞争很容易发生。
  2. 这意味着确实有一部分内存,无论是物理的还是虚拟的,都可以从多个线程中修改,也可以从这些线程中读取。没有明确的所有权概念,所有线程都可以平等地访问内存空间。
  3. 这完全不同。在 Go 中,像上面那样共享内存是可能的,并且很容易发生数据竞争,所以这实际上意味着,修改 goroutine 中的变量,无论是像 int 这样的简单值还是复杂的数据结构,如 map,并通过 channel 机制将值或指向该值的指针发送到不同的 goroutine 来放弃所有权。所以理想情况下,没有共享空间,每个 goroutine 只能看到它拥有的那部分内存。
  4. 这里的通信仅仅意味着一个 channel ,它只是一个队列,允许一个 goroutine 从中读取,因此被通知新部分内存的所有权,而另一个发送它并接受失去所有权。这是一种简单的消息传递模式。

总之,这句话的意思可以总结如下:

Don't overengineer inter-thread communication by using shared memory and complicated, error-prone synchronisation primitives, but instead use message-passing between goroutines (green threads) so variables and data can be used in sequence between those.

这里使用的词序列值得注意,因为它描述了启发 goroutine 和 channel 概念的哲学:Communicating Sequential Processes .

关于go - 解释: Don't communicate by sharing memory; share memory by communicating,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36391421/

相关文章:

c - 正确释放结构的内存

c - 在 CUDA 中使用全局内存初始化共享内存时出错

go - 来自不同 channel 的数据进入 select 语句可以被忽略吗?

go - 在 Go 中创建单向 channel 有什么意义

go - 如何使用go-language server同时作为文件服务器和后端逻辑服务器

xml - 从另一个包扩展结构时的非导出字段

go - 如何从 yaml 文件解析 PodSpec.spec.imagePullSecrets ?

c# - .NET Micro Framework,在内存有限的设备上读取文件

去 channel ,似乎没问题,但它陷入僵局

go - 用函数查找字符串