Linux系统编程(12)——进程间通信-共享内存

    xiaoxiao2022-07-13  209

      共享内存

    用同一个内存块,实现通信。


    共享内存使用方式:

    在内核中先创建共享内存对象(所用函数:frok,shmget)多个进程附加到这个共享内存对象上(所用函数:shmat,和malloc很像)就可以直接读写这个共享内存了

    所用函数:

    shmget函数:用来创建共享内存 

    头文件:

    #include<sys/shm.h> 

    函数:

     int shmget(key_t key, size_t size, int shmflg)

    参数:

    key:这个共享内存段名字,内核中可以同时包含很多共享内存对象,使用不同的 key 区别不同的共享内存对象。

    size:共享内存大小    

    shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的。

    返回值:

    成功返回一个非负整数,即该共享内存段的标识码;失败返回 -1

    int ret=shmget(key,1024,IPC_CREAT | 0666); //IPC_CREAT 存在就打开,不存在就创建 if (ret < 0) { perror("shmget"); return 1; }

    ftok函数:得到key,就是shmget函数中的参数 key

    key_t ftok(const char *pathname,int proj_id);

    返回值:失败返回 -1

    //两个参数一样,得到的值永远一样,参数写啥都不是很重要 key_t key=ftok(".",0x1); //当前文件夹,必须有效路径 //0x1 随便给的 if (key == -1) { perror("ftok"); return 1; }

    ipcs -m:查看系统中的共享内存

    共享内存的生命周期跟随内核。 共享内存一直存在到手动释放或者系统重启。


    shmat函数:将共享内存段连接到进程地址空间

     void *shmat(int shmid, const void *shmaddr, int shmflg); 

    参数:

    shmid: 共享内存标识,类似文件描述符

    shmaddr:指定连接的地址,一般不用添加,都是NULL,也就是让系统说了算。作用连接虚拟地址和物理地址。

    shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY,一般默认添 0 都可以,大部分不使用。

    返回值:

    指针类型,指向共享内存第一个节;失败返回-1


    代码实现:

    重复的代码放头文件:(核心)

    //重复代码,放到 Shm.h 中就好了 #pragma once //防止重复调用 #include<stdio.h> #include<unistd.h> #include<sys/shm.h> //共享内存头文件 static int CreatShm() { //普通函数要加 inline(c++中)/static(C中) 不然会有错误,记住就行,模板就不用 //创建内存 key_t key = ftok(".", 0x1); if (key == -1) { perror("ftok"); return 1; } printf("key= %d\n", key); int ret = shmget(key, 1024, IPC_CREAT | 0666); //IPC_CREAT:存在就打开,不存在就创建,类似文件使用 //返回值类似文件描述符 if (ret < 0) { perror("shmget"); return 1; } printf("ret =%d\n", ret); //共享内存创建之后就要设置权限,也就只有读,写 return ret; }

    创建一个共享内存对象:

    //creat.c 文件中 #include"Shm.h" //创建一个共享内存对象 int main() { int shmid = CreatShm(); return 0; }

    reader.c 文件:读实现

    //reader.c 文件 #include"Shm.h" int main() { //从共享内存读数据 //1.创建一个共享内存对象 int shmid = CreatShm(); //2.附加到共享内存上 char* p = (char*)shmat(shmid, NULL, 0); //3.直接使用,就i是使用malloc 内存一样的使用 printf("reader: %s\n", p);// return 0; }

    write.c文件:写实现

    //write.c 文件 #include"Shm.h" int main() { //从共享内存写数据 //1.创建一个共享内存对象 int shmid = CreatShm(); //2.附加到共享内存对象上 char* p = (char*)shmat(shmid, NULL, 0); //3.直接使用,就i是使用malloc 内存一样的使用 strcpy(p, "hehe\n"); return 0; }

    Makefile文件:

    //Makefile .PHONY:all all : reader writer //一个make生成所有的 reader : reader.c gcc $^ -o $@ writer : writer.c gcc $^ -o $@ .PHONY:clean clean : rm reader writer

    运行自然先写,再读。

    解除共享内存:

    可以用函数 shmdt函数  ,不释放也无所谓没什么影响。

    最新回复(0)