python 共享内存_python共享内存

共享内存(Shared Memory)是最简单的进程间通信方式,它允许多个进程访问相同的内存,一个进程改变其中的数据后,其他的进程都可以看到数据的变化。

共享内存是进程间最快速的通信方式:

`进程共享同一块内存空间。

`访问共享内存和访问私有内存一样快。

`不需要系统调用和内核入口。

`不造成不必要的内存复制。

内核不对共享内存的访问进行同步,因此程序员必须自己提供同步。

使用共享内存:

`某个进程分配内存段。

`使用这个内存段的进程要连接(attach)这个内存段。

`每个进程使用完共享内存段后,要分离(detach)这个内存段。

`在某个地方,必须有一个进程来销毁这个内存段。

Linux的内存模型:

`每个进程的虚拟内存被分为页(page)。

`每个进程维护自己的内存地址到虚拟内存页之间的映射。

`实际的数据存在于进程的内存地址上。

`尽管每个进程有自己的地址空间,多个进程的映射还是可以指向相同的页。

所有的共享内存段的大小,都是Linux内存页大小的整数倍。

Linux的页大小是4KB,不过程序员应该使用getpagesize函数来获得这个值。

分配:shmget

`第一个参数是一个整型的键,用于指定要创建的段。无关的进程可以通过指定同一个键来访问同一段共享内存。

`使用常量IPC_PRIVATE作为第一个参数,可以避免键的冲突。

`第二个参数是分配的段的大小(字节数)。实际分配的字节数会舍弃多余部分到页大小的整数倍。

`第三个参数是位标志,用来表示创建的选项。

``IPC_CREATE:表明要创建新的共享内存空间。

``IPC_EXCL:总是和上一个标志一起使用。如果指定键的共享内存段已经存在,这个标志会导致调用失败;如果没有指定这个标志,调用会返回已经占用这个键的共享内存段。

``模式标志:9个bit的标志,和系统的文件权限使用相同的标志,不过执行标志无效。这些标志定义在中。

`返回值是新创建的或者取得的内存段的标志符(SHMID)。

连接:shmat

`第一个参数是由shmget得到的标志符(SHMID)。

`第二个参数是指向你想要映射到的本进程的地址空间的指针。如果指定NULL,Linux负责选择一个可用的地址。

===================================================

python的共享内存

python的multiprocessing模块提供两种共享内存,sharedctypes与Manager,

Manager效率较低,但支持远程共享内存。

sharedctypes效率较高,快Manager两个数量级,在多进程访问时与普通内存访问相当

结果比较如下:

test array

elapsed 0:00:00.119707

test dict

elapsed 0:00:00.152856

test shared manager list

elapsed 0:00:37.87666

test sharedctypes list in main process

elapsed 0:00:00.154170

test sharedctypes list in subprocess

elapsed 0:00:00.303328

elapsed 0:00:00.327261

elapsed 0:00:00.349312

elapsed 0:00:00.318946

elapsed 0:00:00.364301

elapsed 0:00:00.370176

elapsed 0:00:00.343588

elapsed 0:00:00.348737

代码如下:

import array

from datetime import datetime, timedelta

size = 1000000

def tranverse(a):

t = datetime.now()

for i in range(size):

a[i]

print 'elapsed %s'% (datetime.now()- t)

a = array.array('i', [i for i in range(size)])

print 'test array'

tranverse(a)

a = {}

for i in range(size):

a[i] = i

print 'test dict'

tranverse(a)

from multiprocessing import Manager

manager = Manager()

a = manager.list([i for i in range(size)])

print 'test shared manager list'

tranverse(a)

from multiprocessing.sharedctypes import RawArray

a = RawArray( 'i', [i for i in range(size)] )

print 'test sharedctypes list in main process'

tranverse(a)

from multiprocessing import Process

ps = [Process(target=tranverse, args=(a, )) for i in range(8)]

print 'test sharedctypes list in subprocess'

for p in ps:

p.start()

for p in ps:

p.join()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值