当前位置: 首页 > 面试题库 >

说明:不要通过共享内存进行通信;通过通信共享内存

瞿文柏
2023-03-14
问题内容

我想知道这个著名报价的最真实的解释是什么:

不要通过共享内存进行交流;通过通信共享内存。(R.派克)

在Go Memory Model中,我可以阅读以下内容:

通道上的发送发生在该通道上的相应接收完成之前。(Golang规格)

还有一篇专门的golang文章解释了报价。而关键的贡献是一个工作例子也由Andrew
G.

好。有时谈论太多....我是从“内存规范”引用中得出的,也可以通过查看工作示例来得出:

goroutine1通过通道发送(任何东西)到goroutine2之后,goroutine1通过同一通道接收到之后,goroutine1完成的所有更改(在内存中的任何地方)必须对goroutine2可见。(我的Golang引理:)

因此,我得出了著名报价的脚踏实地解释:

要在两个goroutine之间同步内存访问,您无需通过通道发送该内存。足以从通道接收(甚至什么也没有)。您将在goroutine发送(到通道)时看到(在任何地方)写入的所有更改。(当然,假设没有其他goroutine正在写入同一内​​存。)
更新(2)8-26-2017

我实际上有两个问题:

1)我的结论正确吗?

2)我的解释有帮助吗?

更新(1) 我假设没有 缓冲的通道 。让我们首先限制自己,以免因过多的未知而大修自己。

拜托,让我们也关注两个通过单个通道进行通信的goroutine的简单用例以及相关的内存效果,而不是最佳实践-超出了本问题的范围。

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


问题答案:

从本质上讲,是的。由于通道操作施加了排序约束,因此在通道发送之前分配给变量的任何值都可以在通道读取之后进行观察。但重要的是要记住方程式的另一部分:如果您想
保证
要确保观察到这些值,则必须确保在写入和读取之间没有其他人可以写入这些变量。显然可以使用锁,但同时毫无意义,因为如果您已经将锁和跨线程内存修改结合在一起,那么从通道中可以获得什么好处?您可以传递诸如布尔值之类的简单信息,作为允许对全局数据进行独占访问的令牌,并且就内存模型保证而言(只要您的代码没有错误),
是100%正确的 这可能只是一个糟糕的设计
因为您将在没有充分理由的情况下将所有内容隐式化并按距离进行操作;显式传递数据通常会更加清晰,并且不容易出错。



 类似资料:
  • 我需要在C和Rust应用程序之间共享内存。锈菌——生产者,消费者。 在C语言中,我会创建一个共享内存区域,并将其传递给Rust进行编写。 在C端,我使用了这样的东西: 在锈迹斑斑的一面,我该如何打开存储ID为的内存并对其进行写入?我猜这是一个很好的例子,但却找不到可靠的例子: https://docs.rs/libc/0.2.77/libc/fn.shm_open.html https://doc

  • 问题内容: 我在Linux 2.6中。我有一个环境,其中2个进程通过消息传递模式的简单实现来模拟(使用共享内存)数据交换。 我有一个客户端进程(从父进程(即服务器)派生),该进程将struct(消息)写入使用以下命令创建的内存映射区域(在派生之后): 然后将此指针以链接列表的形式写入到另一个共享内存区域中的队列中,该共享内存区域对于服务器和客户端进程是通用的(因为如果在派生之前使用上面的相同代码创

  • 我正在开发一个应用程序,它必须通过whatsapp共享mp3文件。 我现在的代码如下: 例如,我可以通过Gmail成功共享,但通过whatsapp无法实现。这是我的代码的问题还是whatsapp不允许你共享mp3文件? 提前感谢!

  • 我试图通过在我的iOS应用程序上添加共享文本+URL的功能,但一直失败。 > 发生的情况是Messenger正在打开,但没有内容(文本和url都丢失)。 也许有人知道吗?我的应用程序还在沙箱里,也许这就是原因? 这是我使用的代码:

  • 问题内容: 我的机器在端口8080上运行着jboss,我想在网络上共享jboss服务器,以便我使用jbossws- native-4.0.2运行jboss服务,但是我仍然无法访问网络上的jboss服务器,请帮助。 问题答案: 启动jboss(run.sh或run.bat)时使用选项-b 0.0.0.0,这会将端口绑定到所有网络接口。默认值为localhost,这就是为什么您无法通过网络访问服务器的