通过通信来共享内存 | 青训营笔记

130 阅读3分钟

这是我参与「第五届青训营 」笔记创作活动的第2天

今天上课的时候,老师提到了不要通过共享内存来进行通信,要通过通信来共享内存。一开始接触到这句话的时候,我是十分懵的,通过共享内存来进行通信我可以理解,因为之前学习的语言,不论是java还是python都是使用共享内存来进行通信的。所谓内存共享,我理解成如果在一个系统中,两个线程或进程,都可以读写同一块内存空间,这就是内存共享。这样就可以通过内存共享达到两个不相干的线程进行通信了。以这种方式具有许多的优点,比如系统之间不需要做频繁的沟通,所有必要的信息都在内存中,想取就可以随时取。比如A和B两个游戏角色,B想查阅A的数据,就在内存中找到它,直接读取即可,并且所有的数据都是最新的,没有复制备份,就不会有过期的困扰。但是与此同时,使用这种方法也有相当大的弊端:数据冲突。多线程或多进程场景下,多个对象同时访问同一块数据,几乎一定会产生数据冲突。

为了解决数据冲突的问题,我常常在Java中使用大量的lock和unlock对数据进行管理,但是老师今天提出上文中的第二种方法,通过通道来共享内存,相较于使用lock和unlock解决问题,使用通道共享内存能够更简洁的解决这个问题。以Go语言为例:如果要从一个goroutine传递数据给另一个goroutine,我们可以把这个数据封装成为一个对象,然后将这个对象的指针传入到channel,由channel实现将这个指针传给另外一个goroutine,这样直接说可能还是有点不好理解。可以这样理解,共享内存是直接在内存区域划走一个小区域P,然后在P中储存数据,如果A需要数据,则直接访问P,B需要,也直接访问P,C也同理,于是就会出现一个数据竞争的关系,为了解决这个问题,需要对P设置一个锁,当A需要的时候,会检查锁的存在,如果存在,则等待锁解除,如果不存在,则使用P然后加锁。但是如果是按照第二种方式的话,就是A(或者B或者C等创建这个数据的)创建完成这个数据后,会将数据的指针传入到channel中,这里其实相当于创建完成后,会通知到需要使用这个数据的,告诉大家我数据创建完成了,你们可以使用了。

菜鸟一枚,初次接触到Go,希望大家多指教

参考文章: (120条消息) 不要通过共享内存来通信,要通过通信来共享内存_阿冬哥的博客-CSDN博客

如何理解 Golang 中“不要通过共享内存来通信,而应该通过通信来共享内存”? - 知乎 (zhihu.com)