图文并茂的讲清楚Linux零拷贝技术

news/2024/7/27 10:41:31/文章来源:https://blog.csdn.net/qq_40989769/article/details/136564085

今天我们来聊一聊Linux零拷贝技术,今天我们以一个比较有代表性的技术sendfile系统调用为切入点,详细介绍一下零拷贝技术的原理。

1.零拷贝技术简介


Linux零拷贝技术是一种优化数据传输的技术,它可以减少数据在内核态和用户态之间的拷贝次数,提高数据传输的效率。

在传统的数据传输过程中,数据需要从内核缓冲区拷贝至应用程序的缓冲区,然后再从应用程序缓冲区拷贝到网络设备的缓冲区,最后才能发送出去。

而零拷贝技术通过直接在应用程序和网络设备之间传输数据,避免了中间的拷贝过程,从而提高了数据传输的效率。

Linux零拷贝技术实现方式:

  • sendfile系统调用:sendfile系统调用可以在内核态中直接将文件内容发送到网络设备的缓冲区,避免了数据在用户态和内核态之间的拷贝。

  • splice系统调用:splice系统调用可以将一个文件描述符的数据直接传输到另一个文件描述符,也可以将数据从一个文件描述符传输到网络设备的缓冲区,避免了中间的拷贝过程。

  • mmap和write系统调用:mmap系统调用可以将文件映射到内存中,然后使用write系统调用将内存中的数据直接发送到网络设备的缓冲区,避免了数据在用户态和内核态之间的拷贝。

  • DMA(Direct Memory Access):DMA是一种硬件技术,可以直接将数据从内存传输到网络设备的缓冲区,避免了CPU的介入,提高了数据传输的效率。

2.sendfile系统调用


sendfile系统调用直接在内核中操作文件数据,将数据从源文件描述符复制到目标文件描述符的发送缓冲区,然后通过网络协议栈将数据发送出去。

这样就避免了数据在内核和用户空间之间的复制,提高了传输效率。

sendfile系统调用函数原型:

#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);参数说明:
out_fd:目标文件描述符,用于发送数据。
in_fd:源文件描述符,从该文件读取数据。
offset:指定从源文件的哪个位置开始读取数据,可以为NULL表示从当前位置开始。
count:要传输的字节数。返回值:
成功:返回写入out_fd文件的字节数。
失败:返回-1,并设置errno。

3.sendfile实现原理


3.1 传统方式发送文件


使用传统方式把一个文件通过socket发送出去,我们需要执行一个比较长的路径。

路径:磁盘->文件页缓存->用户缓冲区->套接字缓冲区->网卡。

上下文切换和内存拷贝情况如下:

  • 上下文切换:4次(read调用,read返回,write调用,write返回)

  • DMA拷贝:2次

  • CPU拷贝:2次(文件页缓存->用户缓冲区,用户缓冲区->套接字缓冲区)

3.2 sendfile发送文件


使用sendfile发送文件,相对来说整个路径会短一些。

路径:磁盘->文件页缓存->套接字缓冲区->网卡。

上下文切换和内存拷贝情况如下:

上下文切换:2次(sendfile调用,sendfile返回)

DMA拷贝:2次

CPU拷贝:1次(文件页缓存->套接字缓冲区)

3.3 sendfile实现原理


sendfile实现的核心是管道,管道在Linux系统中应用的比较多,比如说通过管道实现进程间通信。

当需要将文件数据拷贝至socket缓冲区时,会临时创建一个管道(环形缓冲区),将文件数据先拷贝至管道,再将管道数据迁移至socket缓冲区,数据迁移并不是数据拷贝,只是将指针指向内存地址。

3.4 小节


通过采用sendfile发送文件,可以减少2次上下文切换和1次CPU拷贝,如果我们的实际应用场景是需要进行大量的文件发送,采用sendfile能够很大程度上提高系统性能。

相关视频推荐

2024年c/c++程序员如何提升自己的核心竞争力?这套linux c/c++后端服务器开发技术教程不要错过!icon-default.png?t=N7T8https://www.bilibili.com/video/BV1CF4m1L7hU/

Linux C/C++开发(后端/音视频/游戏/嵌入式/高性能网络/存储/基础架构/安全)

需要C/C++ Linux服务器架构师学习资料加qun812855908获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

4.管道


4.1 管道简介


管道在Linux系统中应用很广泛,除了零拷贝技术使用到管道,进程间通信同样使用到管道,那么管道到底是什么?

管道是什么?

管道其实就是一个环形缓冲区,通过管道可以将数据从一个文件拷贝另外一个文件。

管道由struct pipe_inode_info结构体定义,该数据结构有4个重要成员:

  • pipe_buffer:管道缓冲区数组,一个固定长度的数组,每个数组成员都是一个缓冲区,对应一个struct pipe_buffer结构。

  • head:头部序号,表示当前可写缓冲区的位置,需要配合mask使用。

  • tail:尾部序号,表示当前可读缓冲区的位置,需要配合mask使用。

  • ring_size:管道缓冲区数组长度,ring_size - 1计算出mask,head & mask获取当前可写缓冲区数组下标,tail & mask获取当前可读缓冲区数组下标。

管道缓冲区由struct pipe_buffer定义,该结构有3个重要成员:

  • page:页指针

  • offset:数据在页中偏移

  • len:数据长度

管道已满或为空判断?

管道已满判断:

head - tail >= ring_size,表示管道已满。

管道为空判断:

head == tail,表示管道为空。

相关结构体定义 

struct pipe_inode_info是Linux内核中用于管道文件的数据结构。它定义在include/linux/pipe_fs_i.h头文件中。

pipe_inode_info结构体的定义如下:

struct pipe_inode_info {unsigned int head; //头部序号unsigned int tail; //尾部序号unsigned int max_usage; //最大使用量unsigned int ring_size; //缓冲区数组大小unsigned int nr_accounted; //已使用缓冲区数量struct pipe_buffer *bufs; //缓冲区数组......
}

struct pipe_buffer是Linux内核中用于管道(pipe)缓冲区的数据结构。它定义在include/linux/pipe_fs_i.h头文件中。

4.2 管道写


通过head & mask获取缓冲区数组下标,将数据写入pipe_buffer对应的内存页,数据起始位置为offset偏移值,写入的数据长度记录在len成员中。

完成数据写操作后,head头部序号增加1,指向下一个可写位置。

4.3 管道读


通过tail & mask获取缓冲区数组下标,将数据从pipe_buffer对应的内存页读取出来,数据起始位置为offset偏移值,读取数据长度不能大于len记录的数据长度。

完成数据读操作后,len设置成0,pipe_buffer被清空,tail尾部序号增加1,指向下一个可读位置。

5.总结


相比于传统的数据传输技术,零拷贝技术能够大大提高系统性能,在实际项目开发中,我们可以选择符合项目特点的零拷贝技术,以最低的成本提高系统性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_998357.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

乐得瑞 1C to 2C快充线:引领充电数据线新潮流,高效快充解决接口难题

随着科技的不断进步&#xff0c;数据线的接口种类也日渐繁多&#xff0c;但在早些时候&#xff0c;三合一和二合一的数据线因其独特的设计而备受欢迎。这类数据线通常采用USB-A口作为输入端&#xff0c;并集成了Micro USB、Lightning以及USB-C三种接口&#xff0c;满足了当时市…

JeecgBoot Vue3前端项目性能优化按需加载方案

JeecgBoot vue3前端项目在 3.5.5 版本之前&#xff0c;的确存在很严重的性能问题&#xff0c;大家可以参考以下文档进行升级。 按需加载改造方法 1、全局注册地方去掉2、组件改成异步注册3、用不到的大组件可以删掉 【精简项目方案】 大组件 1、富文本 tinyme2、Markdown3、…

数据库压力测试方法概述

一、前言 在前面的压力测试过程中&#xff0c;主要关注的是对接口以及服务器硬件性能进行压力测试&#xff0c;评估请求接口和硬件性能对服务的影响。但是对于多数Web应用来说&#xff0c;整个系统的瓶颈在于数据库。 原因很简单&#xff1a;Web应用中的其他因素&#xff0c;…

C++ · 代码笔记5 · 探索多态与虚函数

目录 前言011虚函数_使用基类指针实现覆盖特性012虚函数_使用引用实现覆盖特性013使用多态场景小例程020构成多态的条件030虚析构函数040纯虚函数051typeinfo运算符_获取类型信息052typeinfo_根据不同类型进行不同操作 前言 本笔记所涉及到的编程环境与 《C 代码笔记1 从C到C…

9道软件测试面试题,刷掉90%的测试程序员

没点真本事真技术&#xff0c;没点面试经验&#xff0c;不了解点职场套路&#xff0c;如何过五关斩六将&#xff1f;如何打败面试官&#xff1f;如何拿下那梦寐以求的offer&#xff1f; 如果你的跳槽意向已经很确定&#xff0c;那么请往下看&#xff01; 跳槽最重要的一步自然…

完美解决VMware中配置suse10虚拟机网络

一、注意&#xff01;&#xff01;&#xff01;配置suse10网络&#xff0c;需要在虚拟机关机状态下进行&#xff0c;否则会配置不成功&#xff1b; 二、配置与主机在同一网段(仅主机模式&#xff0c;网卡一)&#xff1b; 在suse系统关机状态下&#xff0c;Vmware中设置”虚拟网…

UE5 文字游戏(2) C++实时读取CSV文件(游戏开始读取本地CSV剧本)

1.结构体代码 // Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h" #include "Engine/DataTable.h" #include "MyCharacterStats.generated.h"USTRUCT(BlueprintType) struc…

记录 android studio 通过安装NDK 编译C文件,得到需要的so文件

只怪自己太健忘&#xff0c;每次网上查了一圈&#xff0c;搞定后&#xff0c;再遇到又发现不会操作了&#xff0c;特此记下 不废话直接上步骤 &#xff08;1&#xff09; 进入AS的settinging如下界面 &#xff08;2&#xff09;选中图片箭头两个文件 进行下载 &#xff08;…

ChatGPT高效提问——角色提示

ChatGPT高效提问——角色提示 角色提示技巧是一种通过给模型提供具体的角色扮演&#xff0c;指导ChatGPT输出的方法。这个技巧对一个具体的上下文或者听众定制生成的文本很有用。 要使用角色提示技巧&#xff0c;你需要提供明确具体的模型扮演的角色。 例如&#xff0c;如果…

docker 数据卷 详解与实践

常见的数据卷命令 命令 说明 文档地址 docker volume create 创建数据卷 docker volume create docker volume ls 查看所有数据卷 docs.docker.com docker volume rm 删除指定数据卷 docs.docker.com docker volume inspect 查看某个数据卷的详情 docs.docker.co…

【Python】6. 基础语法(4) -- 列表+元组+字典篇

列表和元组 列表是什么, 元组是什么 编程中, 经常需要使用变量, 来保存/表示数据. 如果代码中需要表示的数据个数比较少, 我们直接创建多个变量即可. num1 10 num2 20 num3 30 ......但是有的时候, 代码中需要表示的数据特别多, 甚至也不知道要表示多少个数据. 这个时候,…

qtvs2022工程cmakelist.txt添加QCharts模块

find_package(QT NAMES Qt5 COMPONENTS Core Gui Widgets OpenGL Concurrent Charts Sql Network REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Widgets OpenGL Charts Concurrent Sql Network REQUIRED)这里find_package只是设置搜索路径&#xff0c;为…

阿里云服务器怎么使用?3分钟搭建网站教程2024新版

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网aliyunfuwuqi.com以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流…

【代码随想录算法训练营Day33】1005.K次取反后最大化的数组和;134.加油站;135.分发糖果

❇️Day 33 第八章 贪心算法 part03 ✴️今日任务 1005.K次取反后最大化的数组和134.加油站135.分发糖果 ❇️1005. K次取反后最大化的数组和 本题简单一些&#xff0c;估计大家不用想着贪心 &#xff0c;用自己直觉也会有思路。题目链接&#xff1a;https://leetcode.cn/pr…

如何在Windows上使用Docker,搭建一款实用的个人IT工具箱It- Tools

文章目录 1. 使用Docker本地部署it-tools2. 本地访问it-tools3. 安装cpolar内网穿透4. 固定it-tools公网地址 本篇文章将介绍如何在Windows上使用Docker本地部署IT- Tools&#xff0c;并且同样可以结合cpolar实现公网访问。 在前一篇文章中我们讲解了如何在Linux中使用Docker搭…

从huggingface下载模型像本地加载但是UnicodeDecodeError

我自己是在Linux下出现了这个问题 原文&#xff1a;https://github.com/huggingface/transformers/issues/13674 The path for the AutoModel should be to a directory pointing to a pytorch_model.bin and to a config.json. Since you’re pointing to the .bin file dire…

全局渐变滚动条样式

效果如下&#xff1a; APP.vue<style> /* 整个滚动条 */ ::-webkit-scrollbar {width: 5px;height: 10px; } /* 滚动条上的滚动滑块 */ ::-webkit-scrollbar-thumb {background-color: #49b1f5;/* 关键代码 */background-image: -webkit-linear-gradient(45deg,rgba(255,…

Linux--搭建Zabbix监控系统

11.1 案例分析 要想实时地了解服务器的运行状况并且能在出现问题时及时解决&#xff0c;利用监控软件是一个很好的 途径。 Zabbix&#xff08;免费的&#xff09;是一个基于Web界面的企业级开源监控套件&#xff0c;提供分布式系统监控与网络监视功能。具备主机的性能监控。网络…

基于SpringBoot的中小型超市数据分析系统设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 系统开发相关技术 3 1.1 SpringBoot框架 3 1.1.1发展历程 3 1.1.2 什么是SpringBoot 3 1.1.3 SpringBoot特性 3 1.1.4 SpringBoot的优势 3 1.2 MyBatis框架 4 1.2.1框架简介 4 1.2.2框架特性 4 1.3 Java语言 5 1.3.1 Java语言简介 5 1.3.…

OpenAI-Sora学习手册

通过Sora看2024红利&#xff1a;文生视频&#xff0c;虽然AI不一定是风口&#xff0c;但一定是未来深入到生活工作&#xff0c;乃至思考的必备工具。 目录 Sora介绍 Sora基础介绍 Sora官方网址 Sora的价值 1.物理世界的交互 2.创意世界的绽放 3.多角色、更精准、更细节…