当前位置: 代码迷 >> 综合 >> Linux---共享内存
  详细解决方案

Linux---共享内存

热度:18   发布时间:2023-10-13 21:31:17.0

总结一下共享内存的用法:

1.四个函数总的头文件:

#include<sys/ipc.h>

#include<sys/shm.h>

#include<sys/types.h>

2.共享内存函数由shmget、shmat、shmdt、shmctl四个函数组成

1)shmget函数:创建一个共享内存对象并返回共享内存标识符  (或得到一个共享内存标识符)

函数原型:int shmget(key_t key, size_t size, int shmflg)

第一个参数 key:参数key表示所要创建或打开的共享内存的键值。无论何时创建一个IPC对象(如调用shmget),都需要指定一个key,它的数据类型是key_t。这个key由内核转变为标识符.

  • 0(IPC_PRIVATE):会建立新共享内存对象
  • 大于0的32位整数:视参数shmflg来确定操作。通常要求此值来源于ftok返回的IPC键值,(留个疑问)

第二个参数 size:代表共享内存的大小,一般用sizeof(数据结构)来指定

  • 大于0的整数:新建的共享内存大小,以字节为单位
  • 0:只获取共享内存时指定为0

第三个参数 shmflg : 用来设置shmget函数的操作类型,也可以用来设置共享内存的访问权限。两者可以通过逻辑或(“|”)来连接。其中第一个参数key和第三个参数shmflg共同决定了shmget的操作类型,具体如下:

  • 如果key被设置为IPC_PRIVATE时,第三个参数shmflg无论取什么值,shmget都只用来创建一个新的共享内存区域。
  • 如果key不是被设置为IPC_PRIVATE时,由key和shmflg共同决定shmget是创建还是打开共享内存区域。如函数调用shmget(key, size, IPC_CREAT)中,如果key为内核中某个已经存在的共享区域的键值,则执行打开操作。否则创建一个新的共享内存区域。

例如:            key_t key = ftok("./", 12);
                    shmid = shmget(key, sizeof(int), IPC_CREAT | 0666);

函数返回值: 成功 返回 相应的共享内存标识符,失败返回-1

2)shmat函数:把共享内存区对象映射到调用进程的地址空间

void *shmat(int shm_id,const void *shm_addr,int shmflg);

第一个参数 : shmid 是上面产生的共享内存标识符

第二个参数 : shmaddr 指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置

第三个参数 : shmflg   SHM_RDONLY:为只读模式,其他为读写模式,可以指定为0

函数返回值: 附加好的共享内存地址(成功)  错误 返回-1;

3)shmdt函数:当前进程分离共享内存
int shmdt(const void *shmaddr);

4)shmctl函数
和信号量的semctl函数类似,控制共享内存
int shmctl(int shm_id,int command,struct shmid_ds *buf);
shm_id:共享内存标识符
command: 有三个值
      IPC_STAT:获取共享内存的状态,把共享内存的shmid_ds结构复制到buf中。
      IPC_SET:设置共享内存的状态,把buf复制到共享内存的shmid_ds结构。
      IPC_RMID:删除共享内存
buf:共享内存管理结构体。具体结构可参考定义。

3.共享内存需要注意的问题

共享内存没有同步机制,当多个进程同时向共享内存读写数据时,我们需要使用互斥锁,读写锁,信号量,条件变量等来确保数据的一致性