Go的设计深受Hoare论文的影响.尽管Go与本文中使用的示例语言有很大不同,但这些示例仍然相当容易翻译.除了语法之外,最大的区别是Go将并发通信的管道明确地建模为通道,而Hoare语言的过程直接相互发送消息,类似于Erlang.Hoare在第7.3节中暗示了这种可能性,但是"每个端口在另一个进程中只与一个其他端口连接"的限制,在这种情况下,它将是一个主要的语法差异.
我糊涂了.
Hoare语言中的进程直接相互通信.Go例程也直接相互通信,但使用频道.
那么golang的局限性有什么影响呢.真正的区别是什么?
Ric*_*777 23
答案需要更全面地了解Hoare在CSP上的工作.他的工作进展可归纳为三个阶段:
基于Dijkstra的信号量,Hoare开发了显示器.这些在Java中使用,除了Java的实现包含一个错误(参见Welch的文章Wot No Chickens).不幸的是,Java忽视了Hoare后来的工作.
CSP从中脱颖而出.最初,CSP需要从进程A到进程B的直接交换.Ada和Erlang使用这种集合方法.
CSP于1985年完成,当时他的书首次出版.最终版本的CSP包含Go中使用的频道.与牛津的Hoare团队一起,David May同时开发了Occam,这是一种故意将CSP融入实用编程语言的语言.CSP和Occam相互影响(例如在奥卡姆编程规则中).多年来,Occam仅在Transputer处理器上提供,该处理器的架构适合CSP.最近,Occam已开发出针对其他处理器的方法,并且还吸收了Pi演算以及其他通用同步原语.
因此,回答原始问题,将Go与CSP和Occam进行比较可能会有所帮助.
频道:CSP,Go和Occam都具有相同的语音语义.此外,Go可以轻松地将缓冲添加到频道中(Occam没有).
选择:CSP定义了内部和外部选择.但是,Go和Occam都有一种选择:在Occam中选择 Go和ALT.事实证明,有两种CSP选择在实用语言中不那么重要.
Occam的ALT允许条件保护,但是Go的选择没有(有一个解决方法:通道别名可以设置为nil来模仿相同的行为).
移动性:Go允许通过通道发送通道末端(以及其他数据).这创建了一个动态变化的拓扑结构,超出了CSP的可能范围,但米尔纳的Pi演算是用他的CCS开发的,用来描述这样的网络.
进程:goroutine是一个分叉进程; 它会在它想要时终止并且它没有父级.这不像CSP/Occam,其中流程是组合的.
一个例子在这里有所帮助:首先是Occam(nb缩进很重要)
SEQ
PAR
processA()
processB()
processC()
Run Code Online (Sandbox Code Playgroud)
去吧
go processA()
go processB()
processC()
Run Code Online (Sandbox Code Playgroud)
在Occam案例中,processC在processA和processB终止之前不会启动.在Go中,processA和processB非常快速地分叉,然后processC直接运行.
共享数据:CSP并不直接关注数据.但值得注意的是,Go和Occam之间在共享数据方面存在重要差异.当多个goroutine共享一组共同的数据变量时,竞争条件是可能的; Go的优秀竞赛探测器有助于消除问题.但Occam采取了不同的立场:在编译时阻止共享可变数据.
别名:与上述相关,Go允许许多指针引用每个数据项.奥卡姆不允许使用这些别名,因此减少了检测竞争条件所需的工作量.
关于Hoare的CSP,后两点更少关于May的Occam.但它们是相关的,因为它们直接涉及安全的并发编码.