共享内存的概述 共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。
特别提醒:共享内存并未提供同步机制,也就是说,在第一个进程结束对共享内存的写操作之前,并无自动机制可以阻止第二个进程开始对它进行读取。所以我们通常需要用其他的机制来同步对共享内存的访问
共享内存的流程: 1 创建或打开共享内存 2 挂接共享内存 3 断开共享内存连接 4 删除共享内存
共享内存的API
创建或打开共享内存 int shmget(key_t key, size_t size, int flag); 成功返回共享内存的ID 失败返回 -1; 第二个size 参数必须是兆的整数倍 (1024*n) 第三个参数,shmflg是权限标志,它的作用与open函数的mode参数一样,如果要想在key标识的共享内存不存在时,创建它的话,可以与IPC_CREAT做或操作。共享内存的权限标志与文件的读写权限一样,举例来说,0644,它表示允许一个进程创建的共享内存被内存创建者所拥有的进程向共享内存读取和写入数据,同时其他用户创建的进程只能读取共享内存。
挂接共享内存 **void shmat(int shm_id, const void addr , int flag); 连接共享内存到当前的地址空间;成功返回指向共享的指针,失败返回-1; 第一个参数,shm_id是由shmget函数返回的共享内存标识。 第二个参数,shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。 第三个参数,shm_flg是一组标志位,通常为0。
断开与共享内存的连接 *int shmdt(void addr); 成功返回 0,失败返回-1;
控制共享内存的相关信息 *int shmctl(int shm_id , int cmd, struct shmid_ds buf); 第二个参数,command是要采取的操作,它可以取下面的三个值 : IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。 IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值。 IPC_RMID:删除共享内存段。 第三个参数,buf是一个结构指针,它指向共享内存模式和访问权限的结构。(不关心这些信息,通常取NULL)
在这里插入代码片#include<stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <stdlib.h> #include<string.h> int main() { key_t key; int shmId; char* shmadd; key=ftok(".",1); if(key<0) { printf(“creat key faile\n”); exit(-1);
} shmId=shmget(key,1024*2,IPC_CREAT|0666); if(shmId<0) { printf("creat shm failed\n"); exit(-1); } shmadd=shmat(shmId,NULL,0); strcpy(shmadd,"huangshihai"); sleep(5); shmdt(shmadd); shmctl(shmId,IPC_RMID,NULL); printf("quit\n"); return 0;}
#include<stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <stdlib.h> #include<string.h> int main() { key_t key; int shmId; char* shmadd; key=ftok(".",1); if(key<0) { printf(“creat key faile\n”); exit(-1);
} shmId=shmget(key,1024*2,0); if(shmId<0) { printf("creat shm failed\n"); exit(-1); } shmadd=shmat(shmId,NULL,0); printf("%s\n",shmadd); shmdt(shmadd); return 0;}
