• 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) 删除共享内存,彻底不可用,释放空间。

  • 相关阅读:
    css的三种特性
    css选择器
    margin:0 auto 与 text-align:center 的区别
    JS如何实现点击页面内任意的链接均加参数跳转
    css和js带参数(形如.css?v=与.js?v= 或 .css?version=与.js?version=)
    移动端页面前端设计随笔整理
    理解:Before和:After伪元素
    时下流行的css3页面纵向滑动效果
    webapp网页调试工具Chrome Devtools
    做手机web半年遇到的问题及解决方法
  • 原文地址:https://www.cnblogs.com/yanzi-meng/p/10214755.html
Copyright © 2020-2023  润新知