美文网首页
进程通信之共享内存

进程通信之共享内存

作者: 二进制人类 | 来源:发表于2022-10-02 20:35 被阅读0次

    相关API

    创建

    #include <sys/ipc.h>
    #include <sys/shm.h>
    /**
     * [shmget 通过键来创建共享内存]
     * @param  key    [
     * 共享内存的键值
     *  IPC_PRIVATE:此时在每次调用的时候,都会创建一个新的共享内存;
        非IPC_PRIVATE:有用户自定义key或者通过ftok函数获取
            1) 如果key对应共享内存不存在,则开辟共享内存空间并返回共享内存id;
            2) 如果key对应共享内存已存在,则获取已存在共享内存的id返回。
     * ]
     * @param  size   [共享内存空间大小]
     * @param  shmflg [
     * 共享的访问权限和获取的方式
     *  IPC_CREAT    :创建共享内存,在获取的时候,如果不存在则创建;
        IPC_CREAT | IPC_EXCL  :共享内存存在,不会在创建直接报错。 
     * ]
     * @return        [成功返回共享内存id,失败返回-1且修改errno的值]
     */
    int shmget(key_t key, size_t size, int shmflg);
    

    shell命令

    ipcs -m             #查看系统中的所有共享内存
    ipcrm -m 1802254    #删除编号1802254对应的共享内存;
    

    映射

    #include <sys/types.h>
    #include <sys/shm.h>
    /**
     * [shmat 将共享内存映射给用户空间]
     * @param  shmid   [共享内存的id号]
     * @param  shmaddr [
     * 需要映射的用户地址
     * 如果shmaddr为NULL,则由系统找到合适的为使用的地址空间进行自动映射;
       如果shmaddr为非NULL
         1) shmflg存在SHM_RND,则映射发生在等于shmaddr的地址,舍入到SHMLBA的最近倍数;
         2) shmflg不存在SHMRND,需要按照页面对齐进行映射。
     * ]
     * @param  shmflg  [
     * 共享内存映射方式
     *  0:共享内存具有可读可写权限。
        SHM_RDONLY:只读。
        SHM_RND:(shmaddr非空时才有效)
     * ]
     * @return         [成功返回映射给用户进程的地址,失败返回(void *) -1且修改errno的值]
     */
    void *shmat(int shmid, const void *shmaddr, int shmflg);
    

    解除

    #include <sys/types.h>
    #include <sys/shm.h>
    /**
     * [shmdt 将共享内存和当前进程分离(仅仅是断开联系并不删除共享内存)]
     * @param  shmaddr [需要解除的共享内存空间映射给用户进程的地址]
     * @return         [成功返回0,失败返回-1且修改errno的值]
     */
    int shmdt(const void *shmaddr);
    

    控制

    #include <sys/ipc.h>
    #include <sys/shm.h>
    
    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    

    读操作实例

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    
    int main()
    {
        int ret;
        int shmid;
        key_t key;
        char *shmaddr;
        /* 获取共享内存的键值 */
        key = ftok(".", 'm');
        if (key == -1)
        {
            perror("ftok");
            return -1;
        }
        /* 获取共享内存 */
        shmid = shmget(key, 256, 0777 | IPC_CREAT);
        if (shmid == -1)
        {
            perror("shmget");
            return -1;
        }
        /* 共享内存的映射 */
        shmaddr = shmat(shmid, NULL, 0);
        if (shmaddr == (void *) -1)
        {
            perror("shmat");
            return -1;
        }
        while(1)
        {
            /* 读取共享内存空间中的数据 */
            printf("buf : %s\n", shmaddr);//将共享内存中的数据通过标准输出流输出。
        }
        /* 解除共享内存的映射:不会删除共享内存 */
        ret = shmdt(shmaddr);
        if (ret == -1)
        {
            perror("shmdt");
            return -1;
        }
        system("ipcs -m");
        /* 删除共享内存:从内存中删除 */
        ret = shmctl(shmid, IPC_RMID, NULL);
        if (ret == -1)
        {
            perror("shmctl->IPC_RMID");
            return -1;
        }
        system("ipcs -m");
    }
    

    写操作实例

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    
    int main()
    {
        int ret;
        int shmid;
        key_t key;
        char *shmaddr;
        /* 获取共享内存的键值 */
        key = ftok(".", 'm');
        if (key == -1)
        {
            perror("ftok");
            return -1;
        }
        /* 获取共享内存 */
        shmid = shmget(key, 256, 0777 | IPC_CREAT);
    
        if (shmid == -1)
        {
            perror("shmget");
            return -1;
        }
        /* 共享内存的映射 */
        shmaddr = shmat(shmid, NULL, 0);
        if (shmaddr == (void *) -1)
        {
            perror("shmat");
            return -1;
        }
        while(1)
        {
            /* 将数据写入到共享内存空间中 */
            fgets(shmaddr, 256, stdin);//读标准输入流数据存储到共享内存中。
        }
        /* 解除共享内存的映射:不会删除共享内存 */
        ret = shmdt(shmaddr);
        if (ret == -1)
        {
            perror("shmdt");
            return -1;
        }
        system("ipcs -m");
        /* 删除共享内存:从内存中删除 */
        ret = shmctl(shmid, IPC_RMID, NULL);
        if (ret == -1)
        {
            perror("shmctl->IPC_RMID");
            return -1;
        }
        system("ipcs -m");
    }
    

    相关文章

      网友评论

          本文标题:进程通信之共享内存

          本文链接:https://www.haomeiwen.com/subject/ehldartx.html