再学零拷贝与mmap(代码片段)

ShiPeng ShiPeng     2023-03-21     125

关键词:

一、零拷贝

1.1、背景知识

1.1.1、用户空间

用户空间:运行着用户编写的应用程序的虚拟内存空间。

对于32位的操作系统,每个进程有4GB的虚拟内存空间,其中0~3GB是用户空间,3~4GB 为内核空间。

1.1.2、内核空间

内核空间:运行着操作系统代码的虚拟内存空间。

1.2、下载文件的过程

客户端从服务端下载一个文件的过程:
Step1:调用read函数,从磁盘经过page cache, 读取文件到用户空间的缓冲区
Step2:调用write函数,把用户空间缓冲区的数据,发送给客户端的socket
伪代码:

while ((n = read(file, buf, 4069)) > 0) 
    write(sock, buf , n);

read过程总结:文件从磁盘–>page cache–>用户空间

write的过程总结:文件数据从用户空间–>内核的socket缓冲区,然后网卡驱动负责把socket缓冲区的数据发出去。

读写过程如下图:

从上图可以看出,数据从内核空间复制到用户空间,然后又从用户空间复制回了内核空间,所以,不经过用户空间性能更好,这就是零拷贝技术:

怎样实现上述的过程呢?可通过sendfile。

sendfile系统调用的代码:

#include <sys/sendfile.h>

ssize\\_t sendfile(int out\\_fd, int in\\_fd, off\\_t \\*offset, size\\_t count);

各参数:
1)out_fd:数据接收方文件句柄(一般为 Socket 句柄)。
2)in_fd:数据提供方文件句柄(一般为文件句柄)。
3)offset:如果 offset 不为 NULL,表示从哪里开始发送数据的偏移量。
4)count:表示需要发送多少字节的数据。

实现零拷贝技术的方式,不单有sendfile, 还有mmap, direct IO(不经过page cache, 应用场景如DB,有自己的cache方式,不要借助操作系统提供的方式), splice等。

二、mmap

2.1、传统读写文件的过程


可以看出,传统文件读写,先从磁盘上读取文件到page cache, 再从内核空间中的page cache读出,复制到用户空间的user buffer, 修改后,再写回内核空间的page cache,再刷到磁盘上:
磁盘–>page cache–>user buffer(修改)–>page cache–>磁盘。

2.2、mmap的读写

对于上述传统的文件读写的过程,能否去掉将page cache的数据复制到用户空间缓冲区的过程?

mmap可做到,不同于sendfile, mmap实现方式为:
mmap 系统调用:将用户空间的虚拟内存地址与文件进行映射(绑定),对映射后的虚拟内存地址进行读写操作就如同对文件进行读写操作一样


mmap映射的是文件的页缓存,而非磁盘。

Linux 内核并不会主动把 mmap 映射的 页缓存 同步到磁盘,而是需要用户主动触发,同步 mmap 映射的内存到磁盘有 4 种方式:
1)调用 msync 函数主动进行数据同步(主动)。
2)调用 munmap 函数对文件进行解除映射关系时(主动)。
3)进程退出时(被动)。
4)系统关机时(被动)。

java两种zero-copy零拷贝技术mmap和sendfile的介绍(代码片段)

详细介绍了两种zero-copy零拷贝技术mmap和sendfile的概念和基本原理。文章目录1标准IO2零拷贝2.1sendfile调用2.1mmap调用2.2MQ中的应用1标准IO很多软件是基于server-client模式的,最常见的下载功能需要从Server端的磁盘中将文件通过网络... 查看详情

零拷贝(代码片段)

前言零拷贝这三个字,一直是服务器网络编程的关键字,任何性能优化都离不开。在Java程序员的世界,常用的零拷贝有mmap和sendFile。那么,他们在OS里,到底是怎么样的一个的设计?本文将简单聊聊mmap和sendFile这两个零拷贝。传... 查看详情

操作系统-io零拷贝(代码片段)

...阻塞IOIO多路复用异步IO直接与非直接I/O缓冲与非缓冲I/O零拷贝标准设备标准协议利用中断减少CPU开销利用DMA进行更高效的数据传送零拷贝-传统文件IO零拷贝之mmap零拷贝之sendfilesendfile再优化文件传输总结小文件传输大文件传输相... 查看详情

操作系统-io零拷贝(代码片段)

...阻塞IOIO多路复用异步IO直接与非直接I/O缓冲与非缓冲I/O零拷贝标准设备标准协议利用中断减少CPU开销利用DMA进行更高效的数据传送零拷贝-传统文件IO零拷贝之mmap零拷贝之sendfilesendfile再优化文件传输总结小文件传输大文件传输相... 查看详情

堆外内存与零拷贝(代码片段)

   真正的零拷贝有两种方式:mmap+writeSendfilemmap是一种内存映射文件的方法,即将一个文件或者其他对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对应关系。这样就可以省... 查看详情

mmap(内存映射)sendfile()与零拷贝技术(代码片段)

...f1f;什么是mmap?这些问题都逃不过一个点,就是零拷贝。虽然还有其他的原因,但是这里主要讨论零拷贝。传统的IO方式传统的IO方式底层其实是调用read和write来实现;用户进程通过read向操作系统发起系统调用࿰... 查看详情

rocketmqrocketmq高性能分析之zerocopy零拷贝技术(代码片段)

...messagekey、tag等信息ConsumeQueue随机读+操作系统的PageCache+零拷贝技术ZeroCopy2.1零拷贝技术read(file,tmp_buf,len);write(socket,tmp_buf,len);例子:将一个File读取并发送出去(Linux有两个上下文,内核态,用户态)File文件的经历了4次copy调用read,... 查看详情

mmap详谈(代码片段)

...能开销。同时减少了数据在内核缓冲区和进程地址空间的拷贝次数。  2.使用特殊文件提供匿名内存映射。  3.使用shm_open以提供无亲缘关系进程间的Posix共享内存区。接口说明:void*mmap(void*addr,size_tlength,intprot,intflags,intfd,off_t... 查看详情

rxjava核心思想(看懂再学rxjava)(代码片段)

文章目录【1】背景知识(异步与观察者模式)【2】RxJava有什么作用?【3】RxJava使用的模式:观察者模式【4】RxJava的核心思想(流的思想)【5】最简单的使用:【6】推荐阅读学习的RxJava好文【1】背景知识(... 查看详情

mmap()与阅读块(代码片段)

...到缓冲区,从缓冲区处理完整记录,然后阅读更多。mmap()代码可能会变得非常混乱,因为mmap'd块需要位于页面大小的边界(我的理解),并且记录可能会跨越页面边界。使用fstreams,我可以寻找记录的开头并再次开始阅读,因为... 查看详情

java零拷贝详细讲解(代码片段)

文章目录一、传统IO二、零拷贝1.通过DirectByteBuffer优化2.通过linux2.1sendFile优化3.linux2.4优化三、java实现零拷贝1.mmap2.sendfile结尾一、传统IO传统的IO将一个文件通过socket写出Filef=newFile("test.txt");RandomAccessFilefile=newRandomAc 查看详情

java零拷贝详细讲解(代码片段)

文章目录一、传统IO二、零拷贝1.通过DirectByteBuffer优化2.通过linux2.1sendFile优化3.linux2.4优化三、java实现零拷贝1.mmap2.sendfile结尾一、传统IO传统的IO将一个文件通过socket写出Filef=newFile("test.txt");RandomAccessFilefile=newRandomAc 查看详情

linux内存管理架构之四(mmap内存映射机制)(代码片段)

...规文件操作需要从磁盘到页缓存再到用户主存的两次数据拷贝。而mmap操控文件,只需要从磁盘到用户主存的一次数据拷贝过程。说白了,mmap的关键点是实现了用户空间和内核空间的数据直接交互而省去了空间不同,... 查看详情

存储映射--mmap(代码片段)

存储映射使一个磁盘文件与存储空间中的一个缓冲区相映射。当从缓冲区中取数据,就相当于读文件中的相应字节。将数据存入缓冲区,则相应的字节就自动写入文件。使用这种方法,首先应通知内核,将一个指定文件映射到存... 查看详情

mmap的随机化(代码片段)

http://rk700.github.io/2016/11/22/mmap-aslr/目录正常情况下mmap的随机化CVE-2016-3672pwnable.kr上的题目tiny,我一直没有能够做出来,所以就决定先看看tiny_easy。tiny_easy与tiny很相似,只是栈变成了可执行的,所以可以将shellcode放... 查看详情

mmap与read/write

...都必须经过缓存,当需要从文件读写内容时,都经过内存拷贝的方式与内核中的缓存进行通讯。   1.用read/write方式,用户须向内核指定要读多少,内核再把 查看详情

markdownvector的浅拷贝与深拷贝(代码片段)

查看详情

浅拷贝与深拷贝(代码片段)

浅拷贝与深拷贝一、数据类型数据分为基本数据类型(String,Number,boolean,Null,Undefined,Symbol)和对象数据类型。基本数据类型的特点:直接存储在栈(stack)中的数据对象数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在... 查看详情