共享内存概念
共享内存是通信效率最高的IPC方式,因为进程可以直接读写内存,而无需进行数据的拷备。但是它没有自带同步机制,需要配合信号量等方式来进行同步。
共享内存被创建以后,同一块物理内存被映射到了多个进程地址空间,当有一个进程修改了共享内存的数据,其余的进程均可看见所修改的内容,反之亦然。
mmap函数
函数原型:
void mmap(void adrr, size_t length, int prot, int flags, int fd, off_t offset);
返回值:
成功:返回创建的映射区首地址;
失败:返回MAP_FAILED
具体参数含义:
addr:指向映射区的首地址,这是由系统内核所决定的,一般设为NULL;
length:欲创建的映射区大小;
prot:映射区的权限,一般有如下几种:
PROT_EXEC 映射区域可被执行
PROT_READ 映射区域可被读取
PROT_WRITE 映射区域可被写入
PROT_NONE 映射区域不能存取
flags:指映射区的标志位,MAP_FIXED与MAP_PRIVATE必须选择一个:
MAP_FIXED:对映射区所作的修改会反映到物理设备,但需要调用msync()或者munmap();
MAP_PRIVATE:对映射区所作的修改不会反映到物理设备。
fd:创建的映射区的文件描述符;
offset:被映射文件的偏移量,一般设为0,表示从头开始映射。
mumap函数
函数原型:
int munmap(void *addr, size_t length);
函数作用:
如同malloc之后需要free一样,mmap调用创建的映射区使用完毕之后,需要调用munmap去释放。
例程
写进程:
1#include 2#include 3#include 4#include 5#include 6#include 7#include 8 9typedef struct10{11 int id;12 char name[20];13 char gender;14}stu;1516int main(int argc, char *argv[])17{18 stu *p = NULL;19 int fd = 0;20 stu student = {10, "harry", 'm'};2122 if (argc < 2) {23 printf("useage: ./a.out file");24 return -1;25 }2627 fd = open(argv[1], O_RDWR | O_CREAT, 0664);28 if (fd == -1) {29 printf("ERROR: open failed!");30 return -1;31 }32 ftruncate(fd, sizeof(stu));3334 p = mmap(NULL, sizeof(stu), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);35 if (p == MAP_FAILED) {36 printf("ERROR: mmap failed!");37 return -1;38 }3940 close(fd);4142 while (1) {43 memcpy(p, &student, sizeof(stu));44 student.id++;45 sleep(2);46 }47 munmap(p, sizeof(stu));4849 return 0;50}
读进程:
1#include 2#include 3#include 4#include 5#include 6#include 7 8typedef struct 9{10 int id;11 char name[20];12 char gender;13}stu;1415int main(int argc, char *argv[])16{17 stu *p = NULL;18 int fd = 0;1920 if (argc < 2) {21 printf("useage: ./a.out file");22 return -1;23 }2425 fd = open(argv[1], O_RDONLY);26 if (fd == -1) {27 printf("ERROR: open failed!");28 return -1;29 }3031 p = mmap(NULL, sizeof(stu), PROT_READ, MAP_SHARED, fd, 0);32 if (p == MAP_FAILED) {33 printf("ERROR: mmap failed!");34 return -1;35 }3637 close(fd);3839 while (1) {40 printf("id = %d, name = %s, gender = %c", p->id, p->name, p->gender);41 sleep(2);42 }4344 munmap(p, sizeof(stu));4546 return 0;47}
> 2020 精选 阿里/腾讯等一线大厂 面试、简历、进阶、电子书 「**良许Linux**」后台回复「**资料**」免费获取
#### 看完的都是真爱,点个赞再走呗?您的「三连」就是良许持续创作的最大动力!
1. 关注**原创**「**良许Linux**」,第一时间获取最新Linux干货!
2. 后台回复【资料】【面试】【简历】获取精选一线大厂面试、自我提升、简历等资料。
3. 关注我的博客:[lxlinux.net](http://www.lxlinux.net)