共享内存
1:原理
**
1:共享内存是在物理内存上开辟了一段空间
2:不同的进程可以通过页表映射将开辟的物理内存映射到自己的共享区
3:不同进程在代码当中操作共享区当中的虚拟地址,以达到操作物理内存,从而实现不同进程进行进程间通信
**
如何获取共享内存?
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
key_t : 共享内存标识,只要和当前系统共享内存标识不冲突就可以,传参的时候可以给一个16进制的数字
size : 共享内存的大小
flag :
IPC_CREAT : 当获取的共享内存不存在则创建
IPC_EXCL | IPC_CREAT : 获取自己创建的共享内存,如果获取共享内存的时候发现该标识符的共享内存已经存在,则报错。
按位或上权限 0664
返回值: 返回共享内存的操作句柄
如何附加到进程:
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
shmid : 共享内存操作句柄
shmaddr : 要附加到共享内存哪里。想要附加到共享内存的哪个地址,传值NULL表示操作系统选择合适的共享内存;
shmflg : 0 :读写 IPC_RDONLY :只读
返回值 : 返回共享内存当中附加的地址
共享内存的声明周期是跟随操作系统内核的
ipcs可以查看当前共享内存
int main()
{
int shmid = shmget(KEY , 1024 , IPC_CREAT | 0664);
if(shmid < 0)
{
perror("shmget");
return -1;
}
void *lp = shmat(shmid,NULL,0);
strcpy((char*)lp , "hello linux" );
printf("%s\n",(char*)lp);
while(1)
{
sleep(1);
}
return 0;
}
nattcch 附加进程数量
1:如果一个共享内存被删除掉,共享内存内存标识符会被设置成0x00000000,表示当前共享内存不能被使用
2: 如果删除后,本身还有进程在附加,其实已经将共享内存对应的内存块释放掉了,如果正在附加的进程去使用了已经被删除掉的共享内存,有可能导致崩溃。
3:如果没有进程附加,使用ipcrm删除的时候就直接删除掉了
分离:
int shmdt(const void *shmaddr);
shmaddr:shmat的返回值,共享区地址
操作共享内存
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmid: 共享内存操作句柄
cmd : 告诉shmctl函数做什么操作
IPC_STAT : 获取共享内存属性,第三个参数作为出参
IPC_SET: 设置共享内存属性,第三个参数作为入参
IPC_RMID: 删除共享内存,第三个参数传入NULL