进程间通信
有血缘关系的
父子进程共享内存映射区
没有血缘关系的进程间通信
如何通信?
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小时内删除侵权内容。