共享内存概念
1)原理
将同一块物理地址空间通过内核中的共享内存,分别映射到不同的进程中。
2)共享内存特点
- 共享内存可以通过映射,在用户空间直接获取到共享内存的首地址。用户只需要在用户空间通过操作地址,直接访问到共享内存
- 共享内存是 最高效 的进程间通信方式。进程可以直接通过操控指针,来操作内存空间。
- 多个进程可以同时访问共享内存,即共享内存也是临界资源,所以需要引入进程间的同步互斥机制:
- 信号灯集
- 互斥锁
- 信号量
- 条件变量
- 共享内存独立于进程,等进程结束后,共享内存以及其中的内容不会删除,除非重启操作系统或者手动删除。
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
#include<sys/shm.h>
#include<unistd.h>
int main(int argc, const char *argv[])
{
key_t key=ftok("./",2);
if(key<0)
{
perror("ftok");
return -1;
}
printf("key = %#x\n",key);
int shm=shmget(key,128,IPC_CREAT|0664);
if(shmget<0)
{
perror("shmget");
return -1;
}
printf("shm=%d__%d__\n",shm,__LINE__);
void *Head=shmat(shm,NULL,0);
if(Head==(void *)-1)
{
perror("shmat");
return -1;
}
printf("addr=%p\n",Head);
*(int *)Head=0;
char* ptr = Head+4;
strcpy(ptr,"1234567");
printf("flag=%d\n",*(int *)Head);
system("ipcs -m");
pid_t cpid=fork();
if(cpid>0)
{
while(1)
{
if(*(int *)Head==0)
{
printf("ptr=%s\n",ptr);
*(int *)Head=1;
}
sleep(1);
}
}
else if(cpid==0)
{
int size=strlen(ptr);
while(1)
{
if(*(int *)Head==1)
{
for(int i=0;i<size/2;i++)
{
char arr=*(ptr+i);
*(ptr+i)=*(ptr+size-1-i);
*(ptr+size-1-i)=arr;
}
*(int *)Head=0;
}
}
}
else
{
perror("fork");
}
return 0;
}