(1)文件存储映射I/O(Memory-mapped I/O)
一个磁盘文件与存储空间中的一个缓存区相对应,这样可以在不适合read/write函数的情况下,使用地址(指针)完成I/O操作。具体实现通过内核指定一个文件映射到存储区域中,这个映射可以通过mmap来实现。
mmap函数原型及头文件
函数参数:addr:建立映射区的首地址,由linux内核决定,直接赋值NULL即可;
length:想要建议映射区的大小(应该比磁盘文件小)
prot:映射区权限,有PROT_READ,PROT_WRITE,PROT_READ|PROT_WRITE(权限小于文件的权限)
flags:标志位参数,通常用来设置更新物理区域,设置共享,创建匿名映射区
MAP_SHARED:映射区所做的操作会反应到磁盘上
MAP_PRIVATE:映射区所做的操作会不反应到磁盘上
fd:磁盘文件的文件描述符
offset:映射文件的偏移(4K整数倍,因为内存的最小大小是4K)
返回参数:成功,返回映射区首地址;失败:返回MAP_FAILED宏(一定要检查再使用)
与mmap相对的,有一个函数munmap用来回收mmap申请的映射空间
函数原型及头文件: 成功返回0,失败返回-1.
mmap和munmap函数使用时注意事项:
(2)mmap父子间进程通信
父子间等有血缘关系的进程可以通过mmap来建立映射,只需要改变创建映射区的标志位参数flags.
MAP_SHARED(共享映射) 父子进程共享映射区
MAP_PRIVATE(私有映射) 父子间各自独占映射区
实现父子进程通信,父进程穿件映射区,然后fork子进程,修改映射区的内容,父进程再读取映射区内容,检查是否修改。
父子进程共享:打开的文件和mmap建立的映射区(MAP_SHARED)
(3)匿名映射
父子进程间通信建立一个映射区通常需要打开一个文件,创建好再unlink(删除文件的临时目录项,以便在所有使用这个文件的进程关闭后删除文件),close等操作,比较麻烦,可以采用匿名映射来代替临时文件,具体操作如下:
mmap(NULL.size(任意大小),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
MAP_ANONYMOUS(MAP_ANON)宏是linux操作系统所特有的宏。
在类unix系统中可以使用以下操作完成匿名映射区的建立。
fd=open("/dev/zero",O_RDWR);
p=mmap(NULL,size,PROT_READ|PROT_WRITE,MMAP_SHARED,fd,0);
(4)mmap无血源关系实现进程间通信
mmap是内核借助文件创建一个映射区,多个进程可以通过利用该映射区来完成数据传递,因此无血缘关系的进程也可以进行通信,只需要设置对应的flags即可(设置成MAP_SHARED)
实现非血源关系的进程间的通信,一个进程实现写映射区操作,一个实现读映射区操作(先完成写进程操作,再完成读进程操作)。
写进程操作:
读进程操作