zoukankan      html  css  js  c++  java
  • python共享内存

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

    共享内存是进程间最快速的通信方式:
    `进程共享同一块内存空间。
    `访问共享内存和访问私有内存一样快。
    `不需要系统调用和内核入口。
    `不造成不必要的内存复制。

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

    使用共享内存:
    `某个进程分配内存段。
    `使用这个内存段的进程要连接(attach)这个内存段。
    `每个进程使用完共享内存段后,要分离(detach)这个内存段。
    `在某个地方,必须有一个进程来销毁这个内存段。

    Linux的内存模型:
    `每个进程的虚拟内存被分为页(page)。
    `每个进程维护自己的内存地址到虚拟内存页之间的映射。
    `实际的数据存在于进程的内存地址上。
    `尽管每个进程有自己的地址空间,多个进程的映射还是可以指向相同的页。

    所有的共享内存段的大小,都是Linux内存页大小的整数倍。
    Linux的页大小是4KB,不过程序员应该使用getpagesize函数来获得这个值。

    分配:shmget
    `第一个参数是一个整型的键,用于指定要创建的段。无关的进程可以通过指定同一个键来访问同一段共享内存。
    `使用常量IPC_PRIVATE作为第一个参数,可以避免键的冲突。
    `第二个参数是分配的段的大小(字节数)。实际分配的字节数会舍弃多余部分到页大小的整数倍。
    `第三个参数是位标志,用来表示创建的选项。
    ``IPC_CREATE:表明要创建新的共享内存空间。
    ``IPC_EXCL:总是和上一个标志一起使用。如果指定键的共享内存段已经存在,这个标志会导致调用失败;如果没有指定这个标志,调用会返回已经占用这个键的共享内存段。
    ``模式标志:9个bit的标志,和系统的文件权限使用相同的标志,不过执行标志无效。这些标志定义在<sys/stat.h>中。
    `返回值是新创建的或者取得的内存段的标志符(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()

    参考:
    http://hi.baidu.com/%B1%D8%BC%C7%CE%B4%B6%C1/blog/item/f47e99d5cf0edfc051da4b8b.html
    http://blogold.chinaunix.net/u3/108641/showart_2267237.html
    http://www.rainsts.net/article.asp?id=1018

  • 相关阅读:
    在提交订单时,为了让用户体验更好,一般改成正在提交,后面加三个点,为了让页面更生动,可以把点点改成动态
    js日期格式化
    h5嵌入视频遇到的bug及总结---转载
    字符串中删除多个特定的字符串
    在苹果手机上input有内阴影怎么去除
    把彩色图片置灰色图片
    springmvc入门程序
    Linux常用命令大全
    MyBatis逆向工程详细教程
    MyBatis整合Spring详细教程
  • 原文地址:https://www.cnblogs.com/dkblog/p/1983250.html
Copyright © 2011-2022 走看看