文章目录
共享内存概述
共享内存允许两个或者多个进程共享给定的存储区域。
共享内存的特点
1、共享内存是进程间共享数据的一种最快的方法。一个进程向共享的内存区域写入
了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。
2、使用共享内存要注意的是多个进程之间对一个给定存储区访问的互斥。若一个进
程正在向共享内存区写数据,则在它做完这一步操作前,别的进程不应当去读、写这
些数据。
总结:共享内存是进程间通信方式中效率最高的,原因在于进程是直接在物理内存上进行操作,将物理地址映射到用户进程这,所以只要对其地址进行操作,就是直接对物理地址操作。
共享内存操作
在ubuntu 12.04中共享内存限制值如下
1、共享存储区的最小字节数:1
2、共享存储区的最大字节数:32M
3、共享存储区的最大个数:4096
4、每个进程最多能映射的共享存储区的个数:4096
获得一个共享存储标识符
使用shell命令操作共享内存
查看共享内存
ipcs ‐m
删除共享内存
ipcrm ‐m shmid
创建共享内存
例子
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, char const *argv[])
{
//使用ftok函数获取键值
key_t mykey;
if((mykey = ftok(".", 100)) == -1)
{
perror("fail to ftok");
exit(1);
}
//通过shmget函数创建或者打开一个共享内存,返回一个共享内存的标识符
int shmid;
if((shmid = shmget(mykey, 500, IPC_CREAT | 0666)) == -1)
{
perror("fail to shmget");
exit(1);
}
printf("shmid = %d\n", shmid);
system("ipcs -m");
return 0;
};
共享内存映射(attach)
注意:shmat函数使用的时候第二个和第三个参数一般设为NULL和0,即系统自动指
定共享内存地址,并且共享内存可读可写。
解除共享内存映射(detach)
使用共享内存实现读写操作
write.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
typedef struct{
int a;
char b;
}MSG;
int main(int argc, char const *argv[])
{
//使用ftok函数获取键值
key_t mykey;
if((mykey = ftok(".", 100)) == -1)
{
perror("fail to ftok");
exit(1);
}
//通过shmget函数创建或者打开一个共享内存,返回一个共享内存的标识符
int shmid;
if((shmid = shmget(mykey, 500, IPC_CREAT | 0666)) == -1)
{
perror("fail to shmget");
exit(1);
}
system("ipcs -m");
//使用shmat函数映射共享内存的地址
//char *text;
MSG *text;
if((text = shmat(shmid, NULL, 0)) == (void *)-1)
{
perror("fail to shmat");
exit(1);
}
//通过shmat的返回值对共享内存操作
//strcpy(text, "hello world");
text->a = 100;
text->b = 'w';
//操作完毕后要接触共享内存的映射
if(shmdt(text) == -1)
{
perror("fail to shmdt");
exit(1);
}
system("ipcs -m");
return 0;
}
read.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
typedef struct{
int a;
char b;
}MSG;
int main(int argc, char const *argv[])
{
//使用ftok函数获取键值
key_t mykey;
if((mykey = ftok(".", 100)) == -1)
{
perror("fail to ftok");
exit(1);
}
//通过shmget函数创建或者打开一个共享内存,返回一个共享内存的标识符
int shmid;
if((shmid = shmget(mykey, 500, IPC_CREAT | 0666)) == -1)
{
perror("fail to shmget");
exit(1);
}
system("ipcs -m");
//映射共享内存的地址
//char *text;
MSG *text;
if((text = shmat(shmid, NULL, 0)) == (void *)-1)
{
perror("fail to shmat");
exit(1);
}
//获取共享内存中的数据
//printf("text = %s\n", text);
printf("a = %d, b = %c\n", text->a, text->b);
//解除共享内存映射
if(shmdt(text) == -1)
{
perror("fail to shmdt");
exit(1);
}
system("ipcs -m");
return 0;
}
共享内存控制
例子
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, char const *argv[])
{
//使用ftok函数获取键值
key_t mykey;
if((mykey = ftok(".", 100)) == -1)
{
perror("fail to ftok");
exit(1);
}
//通过shmget函数创建或者打开一个共享内存,返回一个共享内存的标识符
int shmid;
if((shmid = shmget(mykey, 500, IPC_CREAT | 0666)) == -1)
{
perror("fail to shmget");
exit(1);
}
printf("shmid = %d\n", shmid);
system("ipcs -m");
//通过shmctl函数删除共享内存
if(shmctl(shmid, IPC_RMID, NULL) == -1)
{
perror("fail to shmctl");
exit(1);
}
system("ipcs -m");
return 0;
}