回答

14

Go并不妨碍你在goroutines/threads之间共享内存。通过沟通的意思是,你通过一个通道发送一大块数据或一个指向所述块的指针。这有效地将数据的“所有权”转移给渠道的目标读者。请注意,这种所有权转让不是由语言或运行时实施的,而是按惯例。

如果您愿意,您仍然可以完美地从两个goroutines写入相同的内存。换句话说:Go不会阻止你在脚下射击自己,它只是提供了语言语义,这些错误更容易检测到。

如果一个值传递到一个通道中,程序员必须假定该值不再是他要写入同一个goroutine中的值。

func F(c chan *T) { 
    // Create/load some data. 
    data := getSomeData() 

    // Send data into the channel. 
    c <- data 

    // 'data' should now be considered out-of-bounds for the remainder of 
    // this function. This is purely by convention, and is not enforced 
    // anywhere. For example, the following is still valid Go code, but will 
    // lead to problems. 
    data.Field = 123 
} 
+0

优秀的答案! – user984260

+2

如果我正确地理解了你,ITYM“并不妨碍你在脚下自我射击”。 ;) –

+0

非常正确,谢谢!我修复了它。 – jimt

4

这个问题假设共享内存和分布式计算是相反的。这有点像问:RAM和LAN对立?区分CPU /内存节点和CPU /内存节点之间的共享内存并发性会更加清楚。

这是并行处理研究大局的一部分。已经有很多研究项目,其中包括:

  • 开发具有多个CPU共享一个内存,通过某种形式的交换结构(通常是一个Clos网络)加入非冯·诺依曼计算机。 OpenMP将非常适合这些。

  • 开发由CPU集合组成的并行计算机,每个CPU都有自己独立的内存,并且在节点之间有一些通信结构。这通常是MPI的家园,等等。

第一个案例是专门从事高性能计算的兄弟会。这是我们大多数人都熟悉的后一种情况。在这种情况下,通常现在的通信只是通过以太网,但是对于某些特定领域(例如,从Transputer串行链路出现的IEEE1355 SpaceWire)已经(成功)开发了各种更快的低延迟替代方案。

多年来,主流观点认为只有共享内存才能实现高效的并行性,因为通过消息传递的通信成本(天真地)被认为是过分的。对于共享内存并发性,困难在于软件:因为所有东西都是相互依赖的,随着系统变得越来越大,设计并发性越来越困难。核心专业知识是需要的。

对于我们其他人,Go遵循Erlang,Limbo,当然还有Occam推广消息传递作为编排要完成的工作的手段。这源于Communicating Sequential Processes的代数,它为创建任意大小的并行系统提供了基础。CSP设计是可组合的:每个子系统本身可以是更大系统的组成部分,没有理论上的限制。

提到您的问题OpenMP(共享内存)和MPI(分布式内存消息传递),它们可以一起使用。 Go可以被认为与MPI大致相当,因为它促进了消息传递。但它也允许锁定和共享内存。 Go与MPI和OpenMP不同,因为它并不明确涉及多处理器系统。要使用Go进入并行处理的世界,需要一个网络消息传递框架,例如OpenCL,某人正在使用Go API。