如何理解“不要通过共享内存来通信,而应该通过通信来共享内存”?

不要通过共享内存来通信,而应该通过通信来共享内存

这是一句风靡golang社区的经典语,对于刚接触并发编程的人,该如何理解这句话?

阅读 14.2k
4 个回答

https://blog.golang.org/share...

这篇文章里面说的比较清楚了,使用共享内存的话在多线程的场景下为了处理竞态,需要加锁,使用起来比较麻烦。另外使用过多的锁,容易使得程序的代码逻辑坚涩难懂,并且容易使程序死锁,死锁了以后排查问题相当困难,特别是很多锁同时存在的时候。

go语言的channel保证同一个时间只有一个goroutine能够访问里面的数据,为开发者提供了一种优雅简单的工具,所以go原生的做法就是使用channle来通信,而不是使用共享内存来通信。

共享内存会涉及到多个线程同时访问修改数据的情况,那得保证数据的安全性,可见性,那就会加锁,加锁会让并行变为串行,cpu也忙于线程抢锁。不如换一种方式,把数据复制一份,每个线程有自己的,只要一个线程干完一件事其他线程不用去抢锁了,这就是一种通信方式,把共享的以通知方式交给线程,实现并发

其实如果从分布式的角度来理解,就会比较明了了。

打比方,ab两个进程共同对同一个消息队列进行操作,那么,如果使用共享内存的话,是不是这两个进程就必须局限在同一个物理机上,那么通信的意义就大大缩小了。

如果在设计的时候,对于消息队列,只提供读写接口,而对于内部的实现你完全不用去在意,看起来消息队列就像是共享内存一样了。然而你的消息队列可以利用socket进行通信。

所以,上述这句话,不要用共享内存实现通信是指不要让程序一开始就局限在单机上,而是利用通信,也就是封装内部实现,提供接口的方式来进行相应的操作

我认为前者的意思是大家都维护一个状态,后者是每个人都维护一份状态副本。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏