zoukankan      html  css  js  c++  java
  • shmdt() 与 shmctl() 的区别?

    操作共享内存,我们用到了下面的函数
    ==============================================
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>

    int shmid = shmget( key_t shmkey , int shmsize , int flag );
    (void *)shmaddr = shmat( int shmid , char *shmaddr , int shmflag );
    int shmdt( char *shmaddr );

    【shmget】—— 是用来开辟/指向一块共享内存的函数
     参数:
         shmkey    是这块共享内存的标识符,如果是IPC_PRIVATE,则表示使用系统分配的键值创建;
         shmsize   申请内存大小
         flag      标志、权限;
                   当只有IPC_CREAT选项打开时,不管是否已存在该块共享内存,则都返回该共享内存的ID,若不存在则创建共享内存;
                   当只有IPC_EXCL选项打开时,不管有没有该块共享内存,shmget()都返回-1;(即:单独使用该标志无意义)
                   当IPC_CREAT | IPC_EXCL时, 如果没有该块共享内存,则创建,并返回共享内存ID,若已有该块共享内存,则返回-1;
     返回值:
            shmid  内存标识的ID
           
    【shmat】—— 链接上指定ID标识的共享内存
     参数:
         shmid     内存标识ID,由shmget()函数返回;
         shmaddr   (输出参数)共享内存的首地址,同该函数返回值一致;
         shmflag   SHM_RDONLY 只读, 0 可读写;(SHM_COPYSHM_MAPSHM_RND不在此说明)
     
    【shmdt】—— 断开链接的共享内存指针
     参数:
         shmaddr    调用函数shmat()链接上共享内存的指针;

    当一个进程不再需要共享内存段时,它将调用shmdt()系统调用取消这个段,但是,这并不是从内核真正地删除这个段,而是把相关shmid_ds结构的 shm_nattch域的值减1,当这个值为0时,内核才从物理上删除这个共享段
    ========================================================


    用来控制共享内存的shmctl()函数如下:
    =========================================================
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>

    int shmctl( int shmid , int cmd , struct shmid_ds *buf );

    【shmctl】—— 控制共享内存
     参数:
         shmid   共享内存标识ID;
         cmd     IPC_STAT 得到共享内存的状态
                 IPC_SET 改变共享内存的状态
                 IPC_RMID 删除共享内存
         buf     是一个结构体指针。IPC_STAT的时候,取得的状态放在这个结构体中。如果要改变共享内存的状态,用这个结构体指定;
    struct shmid_ds结构体

       struct shmid_ds {

           struct ipc_perm shm_perm;       

           int     shm_segsz;              

           time_t  shm_atime;              

           time_t  shm_dtime;              

           time_t  shm_ctime;              

           unsigned short  shm_cpid;       

           unsigned short  shm_lpid;       

           short   shm_nattch;             

     

                              

     

           unsigned short   shm_npages;    

          unsigned long   *shm_pages;     

                    struct vm_area_struct *attaches;

       };

     

    IPC_RMID 命令实际上不从内核删除一个段,而是仅仅把这个段标记为删除,实际的删除发生在最后一个进程离开这个共享段时。
    ==========================================================


    总结:
    shmdt(addr)使进程中的shmaddr指针无效化,不可以使用,但是保留空间。
    shmctl(shmid,IPC_RMID,0) 删除共享内存,彻底不可用,释放空间。

  • 相关阅读:
    语义化单单的限定在html么?
    转WEB前端开发经验总结(5)
    JavaScript中的null和undefined
    文字上右下环绕广告的写法
    转自森林:最新CSS兼容方案
    转自森林:注释书写规范 Ghost
    【探讨】栈和队列
    转自森林:你是一个职业的页面重构工作者吗?
    Web标准:IE8新特性及IE8安装使用
    转载:09年腾讯校园招聘页面重构的2道面试题
  • 原文地址:https://www.cnblogs.com/yanzi-meng/p/10214755.html
Copyright © 2011-2022 走看看