1.mmap 使用的注意事项
(1)当 open 一个文件时,如果指定了 O_CREAT 标志并且文件不存在,就会新创建一个文件作为映射文件,此时必须调用 ftruncate 或者 lseek+write 设置文件长度,否则任然可以调用 mmap,但是对存储映射区的引用会产生 SIGBUS。另外,如果映射的长度超过了文件长度,访问超过文件长度的映射区也会出错。
(2)munmap 释放映射区时传入的指针必须指向最初分配的位置,否则将会出错(中途可移动映射区指针,但是必须从最开始分配的位置开始释放)。
(3)mmap 指定对映射区的访问权限时不能超过 open 对文件指定的访问权限。
(4)mmap 建立映射区时隐含一次对文件的读,因此打开文件时读权限是必须有的,即使你只进行写操作。
2.使用存储映射区实现父子进程间通信
注意:父子进程的内存空间遵循 读时共享、写时复制,但打开的文件和 mmap 建立的存储映射区在父子进程之间是一直共享的,因此可通过 mmap 建立存储映射区实现父子进程之间的通信。通过以下代码可说明:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
int var = 10;
int main() {
int* p;
int fd;
pid_t pid;
if ((fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) {
perror("open tmpfile");
exit(1);
}
unlink("tmpfile"); //解除硬链接,即删除了临时文件唯一的目录项,使之具备被删除的条件,但此时并未删除
ftruncate(fd, 4); //创建文件大小
p = (int*)mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
perror("mmap failed");
exit(1);
}
close(fd);
if ((pid = fork()) == 0) { //child
sleep(1);
printf("In child: *p = %d, var = %d\n", *p, var);
}
else if (pid > 0) { //parent
*p = 2000; //修改映射区
var = 1000; //修改全局变量
printf("In parent: *p = %d, var = %d\n", *p, var);
wait(NUL

最低0.47元/天 解锁文章
598

被折叠的 条评论
为什么被折叠?



