zoukankan      html  css  js  c++  java
  • 20、IPC共享内存使用注意点

    1、IPC缺陷

    1)XSI IPC都是内核相关的,存在于整个系统范围,但并没有引用计数,可能浪费资源或数据不安全。因此进程结束的时候需要显式地删除结构里面的内容。不像管道那样,进程一结束,管道就被完全删除了。

    2)使用独立的命名空间,添加了很多新的系统调用,导致操作系统复杂。XSI IPC结构在文件系统中没有名字,所有可用于文件的函数都无法使用,为了支持他们不得不增加十几条全新的命令。比如不能用ls命令看到IPC对象,不能用rm命令删除它,不能用chmod命令更改他们的访问权限,就不得不增加新的命令ipcs(1)ipcrm(1)等。

    3)与文件抽象不兼容,不能使用select/epoll等多路复用IO。进程和文件两个抽象是Unix最基本的概念。

    2、IPC具备的优点:(1)可靠;(2)流受控制;(3)面向记录

    3、通过ftruncate来改变文件的大小。通常用在mmap前。因为通过mmap存储映射,最终被映射文件的内容的长度不会超过文件本身的初始大小。所以文件的大小,决定了映射文件的最大额度。可以通过ftruncate来设置想要的文件大小。

    ftruncate(fd, size)。

    4、其实XSI IPCmmap映射很相似,只是后者和一个文件关联起来,而前者是将一块物理内存与当前进程的虚拟地址空间关联。

    5、经过fork后,它将获得父进程数据空间、堆、栈等资源的副本,不同的如下:

    1)父子进程ID不同;

    2)子进程与时间相关的值(time变量等)都被设置为0

    3)父进程的文件锁不会被继承;

    4)子进程未处理的闹钟被清除;

    5)子进程的未处理信号集被设置为空集

    6、关于互斥量,读写锁,条件变量与记录锁:

        互斥量,读写锁,条件变量针对进程,是进程数据,子进程也会从父进程那里继承过来

        而记录锁针对的是文件,子进程不会从父进程那里继承记录锁。

    7、注意点

    1)# cat /proc/sys/kernel/shmmax查看共享内存的最大值

    2)一个进程是可以对同一个共享内存多次 shmat进行挂载,物理内存是指向同一块,如果shmaddrNULL,则每次返回的线性地址空间(进程内地址)都不同,而且指向这块共享内存的引用计数会增加。也就是进程内多块线性空间会指向同一块物理地址。这样,如果之前挂载过这块共享内存的进程的线性地址没有被shmdt掉,即申请的线性地址都没有释放,就会一直消耗进程的虚拟内存空间,很有可能会最后导致进程线性空间被使用完而导致下次shmat或者其他操作失败。

    3)使用共享内存的时候,是用key来作为共享内存的唯一标识的。已经创建的共享内存的大小只能调小,不能调大。

        把key设为IPC_PRIVATE,这样操作系统将忽略键,建立一个新的共享内存,指定一个键值,然后返回这块共享内存IPC标识符ID

    4)创建进程在通知其他进程挂接的时候,建议不使用ftok方式来获取Key,而使用文件或者进程间通信的方式告知。【4

    5)调用shmdt(const void *shmaddr)将进程脱离共享内存区后,数据结构 shmid_ds 中的 shm_nattch 就会减 1 。但是共享段内存依然存在,只有 shm_attch 0 后,即没有任何进程再使用该共享内存区,共享内存区才在内核中被删除。一般来说,当一个进程终止时,它所附加的共享内存区都会自动脱离。也可以调用函数shmctl来显式删除。

    6)如果共享内存已经与所有访问它的进程断开了连接,则调用IPC_RMID子命令后,系统将立即删除共享内存的标识符,并删除该共享内存区,以及所有相关的数据结构;如果仍有别的进程与该共享内存保持连接,则调用IPC_RMID子命令后,该共享内存并不会被立即从系统中删除,而是被设置为IPC_PRIVATE状态,并被标记为"已被删除"(使用ipcs命令可以看到dest字段);直到已有连接全部断开,该共享内存才会最终从系统中消失。

    7)消息队列和信号量均是内核空间的系统对象,经由它们的数据需要在内核和用户空间进行额外的数据拷贝;而共享内存和访问它的所有应用程序均同处于用户空间,应用进程可以通过地址映射的方式直接读写内存,从而获得非常高的通信效率。

    8)创建共享内存时,shmflg参数至少需要IPC_CREAT | 权限标识,如果只有IPC_CREAT 则申请的地址都是k=0xffffffff,不能使用。获取已创建的共享内存时,shmflg不要用IPC_CREAT(只能用创建共享内存时的权限标识,如0640),否则在某些情况下,比如用ipcrm删除共享内存后,用该函数并用IPC_CREAT参数获取一次共享内存(当然,获取失败),则即使再次创建共享内存也不能成功,此时必须更改key来重建共享内存。【5

    9)对于64位进程,同一进程可连接最多268435456个共享内存段;对于32位进程,同一进程可连接最多11个共享内存段,除非使用扩展的shmat

    参考

    1http://blog.sina.com.cn/s/blog_50cbca2d0100r2uo.html

    2http://www.cnblogs.com/mydomain/archive/2011/09/14/2176573.html

    3】 讲解了一个由ftok生成的,但是具有相同的key而产生的案例:

    http://hi.baidu.com/baiduqa/blog/item/0a57a5b1fb70fdb4d9335a15.html

    4】 常见陷阱与分析

    http://www.360doc.com/content/11/0916/17/5407405_148782268.shtml

    5】总结的不错

    http://www.ibm.com/developerworks/cn/aix/library/au-cn-sharemem/index.html

    6http://www.cnblogs.com/skyme/archive/2011/01/04/1925404.html

  • 相关阅读:
    python基础2
    python基础1
    25 CSS3盒子模型
    24 CSS3新增选择器
    23 html5新特性
    22 css初始化
    21 布局技巧
    20 溢出的文字显示省略号
    19 vertical-align 属性应用
    18 CSS三角 用户界面样式
  • 原文地址:https://www.cnblogs.com/mydomain/p/2179553.html
Copyright © 2011-2022 走看看