进程间通信内存映射区笔记

网友投稿 569 2022-05-28

进程间通信

有血缘关系的

父子进程共享内存映射区

没有血缘关系的进程间通信

如何通信?

Mmap 实现内存映射:

必须有一个文件

文件数据什么时候有用:

单纯文件映射

进程间通信:

文件数据是没有用的

Mmap - 创建内存映射

作用:将磁盘文件的数据映射到内存,用户通过修改内存就能修改磁盘文件

函数原型:

void *mmap(

void *addr, //映射区首地址,传NULL

size_t length, //映射区的大小

100byte - 4k

不能为0

一般文件多大,length就指定多大

int prot, //映射区的权限

PROT_READ -- 映射区必须要有读权限

PROT_WRITE

PROT_READ | PROT_WRITE

int flags,//标志位参数

MAP_SHARED

修改了内存数据会同步到磁盘

MAP_PRIVATE

修改了内存数据不会同步到磁盘

int fd, //文件描述符

干嘛的文件描述符?

要映射的文件对应fd

要么得到?

Open()

off_t offset//映射文件的偏移量

映射的时候文件指针的偏移量

必须是4k的整数倍

0

);

返回值:

映射区的首地址 - 调用成功

调用失败:MAP_FAILED

Munmap - 释放内存映射区

函数原型:

int munmap(void *addr, size_t length);

Addr -- mmap 的返回值,映射区的首地址

Length -- mmap的第二个参数,映射区的长度

思考问题:

如果对mmap的返回值(ptr) 做++操作(ptr++),munmap是否能够成功?

不能

Char *pt = ptr;

如果open是O_RDONLY,mmap时port参数指定PROT_READ | PROT_WRITE会怎样?

mmap调用失败

进程间通信之内存映射区笔记

open文件指定的权限应该大于等于mmap第三个参数prot指定的权限

如果文件偏移量为1000会怎样?

必须是4096的整数倍

如果不检测mmap的返回值会怎样?

Mmap 什么情况下会调用失败?

第二个参数length = 0

第三个参数必须指定PROT_READ

Fd 对应的打开权限必须大于等于prot权限

偏移量:必须是4096的整数倍

可以open的时候O_CREAT一个新文件来创建映射区吗?

可以,需要做文件拓展

Lseek

Truncate(fd, length)

mmap后关闭文件描述符,对mmap映射有没有影响?

没有影响

对ptr越界操作会怎样?

段错误

进程间通信

有血缘关系的

父子进程共享内存映射区

没有血缘关系的进程间通信

如何通信?

不能使用匿名映射的方式

只能借助磁盘文件创建映射区 -- temp

不阻塞

a进程(a.c) b进程(b.c)

A.c

Int fd = open("temp");

Void *ptr = mmap(,,,fd,0);

对映射区进行读写操作

B.c

Int fd1 = open("temp");

Void *ptr1 = mmap(,,,,fd, 0);

对映射区做读写操作

mmap实现内存映射:

必须有一个文件

文件数据什么时候有用:

单纯文件映射

进程间通信:

文件数据是没有用的

父子进程永远共享的东西?

文件描述符

内存映射区

#include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; void *ptr; // 1、打开一个文件 fd = open("temp.txt", O_RDWR); // 计算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、创建内存映射区 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } printf("%s", (char *)ptr); // 3、释放内存映射区 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }

如果对mmap的返回值(ptr) 做++操作(ptr++),munmap是否能够成功?

#include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; void *ptr; // 1、打开一个文件 fd = open("temp.txt", O_RDWR); // 计算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、创建内存映射区 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } printf("%s", (char *)ptr); ptr++; // 3、释放内存映射区 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }

如果open是O_RDONLY,mmap时port参数指定PROT_READ | PROT_WRITE会怎样?

#include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; char *pt; void *ptr; // 1、打开一个文件 fd = open("temp.txt", O_RDONLY); // 计算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、创建内存映射区 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } printf("%s", (char *)ptr); // ptr++; pt = ptr; pt++; // 3、释放内存映射区 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }

如果文件偏移量为1000会怎样?

#include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; char *pt; void *ptr; // 1、打开一个文件 fd = open("temp.txt", O_RDWR); // 计算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、创建内存映射区 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 1000); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } printf("%s", (char *)ptr); // ptr++; pt = ptr; pt++; // 3、释放内存映射区 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }

mmap后关闭文件描述符,对mmap映射有没有影响?

#include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; char *pt; void *ptr; // 1、打开一个文件 fd = open("temp.txt", O_RDWR); // 计算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、创建内存映射区 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } close(fd); printf("%s", (char *)ptr); // ptr++; pt = ptr; pt++; // 3、释放内存映射区 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }

父子进程间通信mmap

#include #include #include #include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; pid_t pid; char *pt; void *ptr; // 1、打开一个文件 fd = open("temp.txt", O_RDWR); // 计算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、创建内存映射区 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } // 创建子进程 pid = fork(); if (pid == -1) { perror("fork error"); exit(1); } if (pid > 0) { /* 父进程写数据 */ strcpy((char *)ptr, "爱你美丽,想你美丽!\n"); // 回收子进程 wait(NULL); } if (pid == 0) { /* 子进程读数据 */ sleep(1); printf("%s", (char *)ptr); } /* printf("%s", (char *)ptr); // ptr++; pt = ptr; pt++; */ // 3、释放内存映射区 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } close(fd); return 0;

想使有血缘关系之间的进程进行通信,可以使用匿名内存映射的方式进行通信。

#include #include #include #include #include #include #include #include #include int main(int argc, char argv[]) { int len = 4096; int ret; pid_t pid; char *pt; void *ptr; // 2、创建内存映射区 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } // 创建子进程 pid = fork(); if (pid == -1) { perror("fork error"); exit(1); } if (pid > 0) { /* 父进程写数据 */ strcpy((char *)ptr, "爱你美丽,想你美丽!\n"); // 回收子进程 wait(NULL); } if (pid == 0) { /* 子进程读数据 */ sleep(1); printf("%s", (char *)ptr); } // 3、释放内存映射区 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }

内存映射使用在没有血缘关系的两个进程间的通信

write.c

#include #include #include #include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len; int ret; pid_t pid; char *pt; void *ptr; // 打开文件 fd = open("temp.txt", O_RDWR | O_CREAT, 0664); ftruncate(fd, 4096); len = lseek(fd, 0, SEEK_END); // 2、创建内存映射区 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } // 操作共享内存映射区写数据 while (1) { char *p = (char *)ptr; p += 1024; strcpy(p, "meili i love you ,you go to where?\n"); sleep(2); } // 3、释放内存映射区 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } close(fd); return 0; }

read.c

#include #include #include #include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len; int ret; pid_t pid; char *pt; void *ptr; // 1、打开文件 fd = open("temp.txt", O_RDWR | O_CREAT, 0664); ftruncate(fd, 4096); len = lseek(fd, 0, SEEK_END); // 2、创建内存映射区 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } // 操作内存处理数据 while (1) { sleep(1); printf("%s", (char *)ptr + 1024); } // 3、释放内存映射区 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } close(fd); return 0; }

任务调度

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java类和对象的设计
下一篇:HDFS系列(1) | HDFS文件系统的简单介绍
相关文章