这次我们通过分析python的multiprocessing的源码,来看看Value Array怎么通过mmap ctypes实现的多进程之间的共享内存.

     当第一次使用python多进程模块(multiprocessing)的Value Array做数据共享,就觉得一定是基于mmap实现的。 当然python文档中也说明是共享内存的方式了。 mmap只是提供了文件映射内存到进程地址空间的的一种方法,通过这方法你是可以读写数据的.    

      直接去读写数据会让人烦恼的,对于上层应用不应该对他的数据格式进行解析,我向mmap里面flush一条数据 “521+我是峰云” 这样的组合,我怎么读? 如果数据是这么写进去的,我是需要约定的数据格式, 像http那样。   有什么解决方法?  首先想到的是json,pickle序列化.  那么multiprocessing Value是如何解决的?  他用ctypes内置的基本数据结构实现的,这里准确说 C的数据结构,我们只是用ctypes引用使用而已。 ctypes可以很好的切分内存,转换成可用的数据结构。 

该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新. http://xiaorui.cc/?p=3290

额外说一下,multiprocessing 的Value和Array实现的方法大同小异,只是选用不同的ctypes数据类型而已.  另外multiprocessing官方有两种方法提供给我们,一个是共享内存的方式,另一个是Manager 网络的方式,因为借助了网络,Manager的数据类型要比共享内存要多。

对于我们多进程应用来说,我们只需要找到文件映射的内存空间,进一步找到数据结构就可以实现数据共享了。 

multiprocessing Value使用方法:

我们说下 ctypes用法, ctypes大多是用来调用C库的,当然你也可以使用它的基本数据类型。


下面简单说说,怎么通过调用ctypes类型的指针函数来创建指针实例:

创建以整形数组

详细的ctypes用法,请到官方查看 , https://docs.python.org/2/library/ctypes.html

接着粗略的聊聊multiprocessing共享内存的实现方法.

multiprocessing提前设定的ctypes映射表,这样对你来说只需要传递符号就可以了。 


下面这个Value就是我们用来多进程共享数据的函数,下面我们一步步的看看他是如何实现的.  


python2.7/multiprocessing/heap.py

这里mmap传递-1是个什么概念,一般咱们都是传递文件描述符的。

Only -1 is accepted on Unix: on my 64-bit Ubuntu box with Python 2.6.5, mmap.mmap(0, 256) fails with errno=19 (No such device) and mmap.mmap(-1, 256) works fine.
And, To map anonymous memory, -1 should be passed as the fileno along with the length.

参数fd为即将映射到进程空间的文件描述字,一般由open()返回,同时,fd可以指定为-1,此时须指定flags参数中的MAP_ANON,表明进行的是匿名映射(不涉及具体的文件名,避免了文件的创建及打开,很显然只能用于具有亲缘关系的

下面的代码通过mmap ctypes实现了一个简单的数据共享, 这样对于我们来说,可以像操作python对象那样操作映射的内存地址

代码引用地址:
https://blog.schmichael.com/2011/05/15/sharing-python-data-between-processes-using-mmap/


a.py 设置mmap,调用ctypes创建一个c_int对象 。 a.py在共享内存中一共创建了两个数据结构,先是用c_int变量i,然后使用struct.calcsize拿到 变量 i 的数据大小,然后用from_buffer加上offset申请对象。这样能保证内存连续性。 

b.py , 可以接受a.py扔过去的值, 流程一样.

对于multiprocessing共享内存方式来通信就说这么多了,上面的描述讲解还是比较粗略,如果大家想刨根问底,可以看 multiprocessing sharedctypes.py heap.py forking.py模块。 下次跟大家聊聊manger的实现。



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!
暂无相关产品

发表评论