ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux下IPC之共享内存的使用方法

2022-01-29 02:02:16  阅读:216  来源: 互联网

标签:IPC include shm key Linux shmid 共享内存 SHM size


基本参考 《Unix环境高级编程》第14.9节共享内存来学习。

参考blog:https://blog.csdn.net/weixin_45794138/article/details/121256996

需要说明的

讲shmget(key,size, flag)函数时,书上大概意识是说,

想访问已有的shm时,key不应与IPC_CREATE 同时指定。

实际上测试,可以二者同时指定:

  • 已有此key的shm且size满足要求(已有shm的size ≥ 函数中指定的size)时,直接返回已有的shmid。
    若size不满足,则失败返回-1

  • 若未有此key的shm,则使用 key 和 size 创建新的IPC结构,并返回shmid;创建失败则返回-1.

getshm()函数,常见的调用示例:

点击查看代码
int shmid = shmget(key, SHM_SIZE, IPC_CREAT|IPC_EXCL|0666);  //强制创建新的,且指定访问权bits位

int shmid = shmget(key, SHM_SIZE, 0);  //强制使用已有的,且满足 size >= SHM_SIZE, 否则失败返回-1
int shmid = shmget(key, SHM_SIZE, IPC_CREAT);  //若无此key的shm,则创建新的shmid并返回,创建失败返回-1;
                                               //若已有此key的shm且size满足要求,直接返回已有的shmid;
                                               //已有此key的shm但size不满足要求,同样失败返回-1.

Server端示例代码

废话不多说, 赶紧上代码,首先是server端,开辟共享内存shm并写入内容进去:

点击查看代码
#include <stdio.h>
//#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHM_PATH  "/var/run/pnkey"
#define SHM_SIZE 128

int main(){

    key_t key = ftok(SHM_PATH, 0x6666);  //file to key,传入的文件SHM_PATH必须存在(权限不要求),否则失败返回-1
    if(key<0){
        printf("shm key return -1. Please contact the device vendor.");
    }

    // //强制创建1块新的共享内存shm,并设置访问权限位.
    // int shmid = shmget(key, SHM_SIZE, IPC_CREAT|IPC_EXCL|0666);
    // if(shmid <0 ){
    //     printf("Failed to get/create share memory with key= 0x%8x.\n", (int)key );    
        
    //     //先尝试获取已有的shm
    //     shmid = shmget(key, 0, 0);
    //     if(shmid <0 ){
    //         printf("Failed to retrive share momory with key= 0x%4x.\n", (int)key);
    //         return -1;
    //     }
    //     //查看获取的shm的size
    //     struct shmid_ds * buf;
    //     int rst = shmctl(shmid, IPC_STAT, buf);
    //     if(buf->shm_segsz != SHM_SIZE){
    //         printf("The retrived SHM has different size.\n");
    //         return -1;
    //     }
    // }
    
    //获取此key已有的共享内存shm,未找到时创建新的.[可替代上面的手动检索!]
    int shmid = shmget(key, SHM_SIZE, IPC_CREAT);

    //attach到进程空间
    char * addr = shmat(shmid, NULL , 0);
    if(addr <= 0 ){
        printf("failed to attach share memory.\n");
        return -1;
    }

    //使用shm,写入
    sprintf(addr, "%s", "共享内存,您好~\n");

    return 0;
}

Client端示例代码

接着是client端的,查找出已有的共享内存shm,并从中读取

点击查看代码
#include <stdio.h>
#include <string.h>
//#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>


#define SHM_PATH  "/var/run/pnkey"
#define SHM_SIZE  128

int main(){

    key_t key = ftok(SHM_PATH, 0x6666);
    if(key<0){
        printf("shm key return -1. Please contact the device vendor.");
    }

    char buf[128];

    //int shmid = shmget(key, SHM_SIZE, IPC_CREAT);
    int shmid = shmget(key, SHM_SIZE, 0);
    if(shmid <0){
        printf("Failed to retrive share memory.\n");
        return -1;
    }

    char * addr = shmat(shmid, NULL, SHM_RDONLY);  //只读挂载
    if(addr<=0){
        printf("Failed to map share memory.\n");
        return -1;
    }

    //使用shm,打印字符串.
    strcpy(buf, addr);
    printf("%s", buf);
    printf("%s", addr); //可以直接打印,不必strcpy; 但得考虑同步问题,防止读写并发冲突。

    return 0;
}

标签:IPC,include,shm,key,Linux,shmid,共享内存,SHM,size
来源: https://www.cnblogs.com/zhw618/p/15854216.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有