为了账号安全,请及时绑定邮箱和手机立即绑定

可以在两个单独的进程之间共享内存中的数据吗?

可以在两个单独的进程之间共享内存中的数据吗?

慕尼黑8549860 2019-10-09 15:43:12
我有一个使用Twisted的xmlrpc服务器。服务器在内存中存储了大量数据。是否有可能运行辅助的单独的xmlrpc服务器,该服务器可以访问第一个服务器中的内存中的对象?因此,serverA启动并创建一个对象。serverB启动,可以从serverA中的对象读取。*编辑*要共享的数据是一百万个元组的列表。
查看完整描述

3 回答

?
Helenr

TA贡献1780条经验 获得超4个赞

如果没有对Python核心运行时进行深入和黑暗的重写(以允许强制使用共享内存的给定段并确保不同进程之间的地址兼容的分配器),就无法从任何一般意义上“共享内存中的对象”。该列表将包含一百万个元组的地址,每个元组均由其所有项目的地址组成,并且每个地址都将由pymalloc分配,这种方式不可避免地在进程之间变化,并遍及整个堆。

在Windows以外的几乎所有系统上,都有可能产生一个子进程,该子进程本质上具有对父进程空间中对象的只读访问权限……只要父进程也不会更改这些对象。可以通过致电获得os.fork(),实际上是“快照”当前进程的所有内存空间,并在复制/快照上启动另一个同时进行的进程。在所有现代操作系统上,这都归功于“写时复制”方法:在分叉后未真正复制任一进程未更改的虚拟内存页面(实际上是共享对相同页面的访问) ; 一旦任何一个进程修改了先前共享页面中的任何位,poof,即会复制该页面,并修改了页面表,因此修改过程现在具有其自己的副本,而另一个进程仍然看到原始页面。

在某些情况下,这种极其有限的共享形式仍然可以挽救生命(尽管极为有限:例如,请记住,由于引用计数的原因,对共享库添加引用将被视为“更改”该对象,因此将强制页面复制!)...当然除外,在Windows上除外。有了这个例外(我认为不会涵盖您的用例),共享包含其他对象的引用/指针的对象图基本上是不可行的-几乎所有现代语言(包括Python)中感兴趣的对象集属于这种分类。

在极端(但足够简单)的情况下,可以通过放弃此类对象图的本机内存表示来获得共享。例如,一百万个元组的列表每个都有十六个浮点数,实际上可以表示为一块128 MB共享内存的块-双精度IEEE表示形式的所有16M浮点数首尾相连-带有一点点填充要使它看起来像“顶”,您将以通常的方式解决问题(当然,毕竟不是那么简单的填充程序还必须解决极其繁琐的进程间同步问题,肯定会出现;-)。从那里开始,它只会变得更加毛发且更加复杂。

现代并发方法越来越无视共享的方法,而无共享的方法更是如此,在这种方法中,任务通过消息传递进行通信(即使在使用线程和共享地址空间的多核系统中,同步问题和性能也会受到影响)当大面积的内存同时被多个内核主动修改时,会在缓存,流水线停顿等方面引起麻烦。

例如,Python标准库中的多处理模块主要依靠酸洗和来回发送对象,而不是共享内存(肯定不是以R / W方式!!)。

我意识到这对OP来说不是可喜的消息,但是如果他确实需要使多个处理器正常工作,那么他最好考虑将它们必须共享的任何内容驻留在可以通过消息传递进行访问和修改的地方- -数据库,内存缓存集群,除了将这些数据保留在内存中并根据请求发送和接收它们之外什么也不做的专用进程,以及其他此类以消息传递为中心的体系结构。


查看完整回答
反对 回复 2019-10-09
  • 3 回答
  • 0 关注
  • 1669 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信