- 头文件
#include1.1、shmge :创建共享内存#include
int shmget(key_t key, size_t size, int shmflg);
- key:创建共享内存的关键字
IPC_PRIVATE:创建新的共享内存
或者由 ftok 函数产生
或者自定义一个key- size:设定共享内存的大小
- shmflg:共享内存的访问权限
0 访问已存在的IPC
IPC_CREAT | 0644:不存在则创建新的IPC
IPC_EXCL和IPC_CREAT一起用 判断IPC是否存在
1.2、shmat:映射共享内存
- 返回值
>0 共享内存ID ,类似文件描述符
-1 出错
void *shmat(int shmid, const void *shmaddr, int shmflg);
- shmid:共享内存的id号
- shmaddr:指定共享内存在当前进程中的地址,通常为NULL
- shmflg:共享内存的使用权限
SHM_RDONLY:以只读的方式使用此内存段
其他:以读写的方式
1.3、 shmdt:解除映射
- 返回值
>0 共享内存的首地址
-1 失败
int shmdt(const void *shmaddr);
- addr:调用shmat时返回的共享内存首地址
1.4、shmctl:对共享内存的一些操作
- 返回值
0 成功
-1 失败
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
二、简单应用
- shmid:共享内存的id号
- cmd:对共享内存的操作
IPC_RMID :删除共享内存段
IPC_STAT:获取shmid_ds结构,并将其放在由buf指向的结构中
IPC_SET:按buf指向结构中的值设定此段相关结构中的一些内容
SHM_LOCK:将共享内存锁定在内存中
SHM_UNLOCK:解锁- buf :设置共享内存时需要的数据或接收共享内存属性的内存地址
删除共享内存时可以为NULL
- 共享内存不依赖与进程而存在(只要不主动删除,进程退出了,共享内存还在)
- 键key可以自己指定,也可以通过ftok生成
- 可以通过键或shmid再次访问共享内存
- 键 和 shmid 都是全局唯一的
- 对于不同的进程
同一个key,shmget()返回的id一样
同一个shmid,shmat()返回的地址一样 - 可以同时读写共享内存
#include#include #include #define KEY 10//只要不和已有的一样,可任意设置 int main() { int id; char *buf; //创建共享内存 大小为1024 id = shmget(KEY,1024,IPC_CREAT | 0644); if(id == -1){ perror("shmget"); exit(1); } printf("id = %dn", id); //映射共享内存 buf = (char *) shmat(id,NULL,0); printf("buf : %pn",buf); //写程序 for(int i = 0;i<10;i++){ buf[i] = (char)('a'+i); } printf("write : %sn",buf); //读程序 //printf("read : %sn",buf); shmdt(buf);//取消映射 //shmctl(id,IPC_RMID,NULL);//删除共享内存 return 0; }
- 使用ipcs命令查看共享内存
$ ipcs
key = 0x0000000a 换算成十进制就是 10
shmid =10 是按最小可用来分配的
- 加 IPC_EXCL再执行write / 删除 IPC_EXCL再执行write
#include#include #include #include #define PATH "./shm" //设置共享内存要关联的文件 #define Proj_Id 16 //只要不和已有的一样,可任意设置 typedef struct { char msg[10]; int num; }Data; int main() { int key,shm_id,size; Data *buf; key = ftok(PATH,Proj_Id); if(key == -1){ perror("ftok"); exit(1); } //也可以不关联文件,自己设置key的值 // key = 16; //只要不和已有的一样,可任意指定 printf("key = %dn",key); size = sizeof(Data)*10; printf("size = %dn",size); shm_id = shmget(key, size,IPC_CREAT | 0644); if(shm_id == -1){ perror("shmget"); exit(1); } printf("shm_id = %dn", shm_id); buf = (Data *) shmat(shm_id,NULL,0); printf("buf : %pn",buf); printf("开始写入:n"); for(int i = 0;i<10;i++){ //注释下面两行即可变成读程序 (buf+i)->msg[0] = (char)('a'+i); (buf+i)->num = i+1; printf("num = %d, msg = %s n",(buf+i)->num, (buf+i)->msg); sleep(1); } printf("写入结束:n"); shmdt(buf); return 0; }



