为了多个进程能够
交换信息
,在内核中留出一段内存区,可以由需要访问的多个进程把内存区的地址映 射到自己的进程中,可以操作这段空间,可以进行通信。 进程就可以直接读写这段空间,避免拷贝,提高效率。
共享内存的使用步骤:
1. 创建
/
打开共享内存
· 2. 映射共享内存,把共享内存的空间映射到进程中(以地址提供地址)
3. 进行操作
4. 撤销共享内存映射
5. 删除共享内存对象
使用共享内存需要用到的函数
1、
创建
/
打开共享内存
#include <sys/ipc.h>
#include <sys/shm.h>
//创建 、 打开一个共享内存
int shmget(key_t key, size_t size, int shmflg);
参数:
参数1:key_t key//:要创建/打开的共享内存的编号
参数2:size_t size//:要创建的共享内存的空间大小,以字节为单位
参数3:int shmflg//:选项 IPC_CREAT:要创建 权限:读写执行
返回值:int
成功:返回打开/创建的共享内存的标识id,打开的共享内存是谁
失败:-1,设置错误码
2、 映射共享内存,把共享内存的空间映射到进程中(以地址提供地址)
#include <sys/types.h>
#include <sys/ipc.h>
//计算key值
key_t ftok(const char *pathname, int proj_id);
参数:
参数1:const char *pathname:文件路径
参数2:int proj_id:
#include <sys/types.h>
#include <sys/shm.h>
//映射共享内存到进程中
void * shmat(int shmid, const void *shmaddr, int shmflg);
参数:
参数1:int shmid:打开的共享内存,映射哪个共享内存
参数2:const void *shmaddr:共享内存映射到进程中,具体映射到进程的哪个的地址
NULL:系统自动选择地址完成映射
参数3:int shmflg:选项
SHM_RDONLY:共享内存只读
0:读写
返回值:
void *:指针,地址
成功:返回映射到进程的地址
失败:返回(void *)-1
.3、撤销共享内存映射
//撤销共享内存的映射
int shmdt(const void *shmaddr);
参数:
参数1:
const void *shmaddr://刚才映射的地址,要进行撤销
返回值:
成功:返回0
失败:返回-1,设置错误码
4、共享内存控制
#include <sys/ipc.h>
#include <sys/shm.h>
//共享内存控制
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
参数1:
int shmit:打开的共享内存,映射哪个共享内存
参数2:
int cmd:控制命令
IPC_STAT:获取共享内存信息,把共享内存的信息,存储在第三个参数表示的地址中
IPC_SET:设置共享内存信息,把共享内存的信息存储到结构体中,作为第三个参数地址,设置到内核
IPC_RMID:关闭共享内存,删除,第三个参数为NULL
参数3:
struct shmid_ds *buf://结构体地址,设置、获取都是使用这个地址,表示存储到内核,存储到程序
返回值:
失败:返回-1
成功:IPC_RMID返回0
使用案例:
写的程序
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
key_t key = ftok("/home/ubuntu",10);//计算出key值,应该和创建的进程使用的key一致
int shmid = shmget(key,1024,0666 | IPC_CREAT);//创建 打开共享内存,得到标识
if(shmid < 0)
{
perror("shm get error");
return -1;
}
char * p = shmat(shmid,NULL,0); //映射共享内存的地址
while(1)
{
if(strcmp(p,"quit\n") == 0) //quit退出
{
break;
}
printf("%s",p);
sleep(1);
}
shmdt(p); //撤销共享内存
shmctl(shmid,IPC_RMID,NULL); //删除共享内存
return 0;
}
读的程序
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
key_t key = ftok("/home/ubuntu",10);//计算出key值
int shmid = shmget(key,1024,0666 | IPC_CREAT);//创建 打开共享内存,得到标识
if(shmid < 0)
{
perror("shm get error");
return -1;
}
char * p = shmat(shmid,NULL,0);
while(1) //唯一不同的地方
{
fgets(p,1024,stdin);
if(strcmp(p,"quit\n")==0)
{
break;
}
}
shmdt(p);
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
其实这种通信的话,在进行通信的时候,一但共享内存的值发生改变,那么其内存空间的值也就发生改变了。一变则全部都变了。