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

  • 相关阅读:
    BNU 51002 BQG's Complexity Analysis
    BNU OJ 51003 BQG's Confusing Sequence
    BNU OJ 51000 BQG's Random String
    BNU OJ 50999 BQG's Approaching Deadline
    BNU OJ 50998 BQG's Messy Code
    BNU OJ 50997 BQG's Programming Contest
    CodeForces 609D Gadgets for dollars and pounds
    CodeForces 609C Load Balancing
    CodeForces 609B The Best Gift
    CodeForces 609A USB Flash Drives
  • 原文地址:https://www.cnblogs.com/dkblog/p/1983250.html
Copyright © 2011-2022 走看看