OpenHarmony实战开发-文件上传下载性能提升指导。

概述

在开发应用时,要实现高效的客户端跟服务器之间数据交换,文件传输的性能是至关重要的。一个数据交换性能较低的应用会导致其在加载过程中耗费较长时间,在很多的场景造成页面卡顿,极大的影响了用户体验。相反,一个数据交换高效的应用,则会让应用变得更加流畅。

本文将介绍两种常见的上传下载传输和网络请求的关键技术:数据压缩和断点续传,可提升上传下载的性能、减少宽带占用,从而提高数据传输效率。

上传下载接口

目前系统内提供给文件上传下载可用的模块有@ohos.net.http模块和@ohos.request模块。@ohos.net.http模块提供基础的HTTP数据请求能力,功能较为基础,本文不做介绍。@ohos.request模块主要给应用提供上传下载文件、后台传输代理的基础能力。它具备任务管理系统的默认并发功能,简化下载功能的实现和管理,提升数据传输的安全,整合通知机制,新增任务状态与进度查询功能,具有灵活性、高效性、可扩展性、可靠性、一致性和安全性的优势。

具体来说,@ohos.request模块包括以下功能:

  1. 任务管理:任务管理操作包括创建任务、暂停任务、恢复任务、删除任务、文件上传、文件下载、系统通知等。创建的任务分为前端任务和后台任务。前端任务是立即的、模态界面的、同步的,跟随应用的生命周期,通常数据量较小、耗时短,例如发布微信朋友圈、微博,通常优先级高且倾斜带宽资源。后台任务为可等待的、任意界面的、异步的,通常数据量较大、耗时长,例如缓存一部电影、同步数百兆字节乃至若干吉字节的数据,优先级相较于前端任务低且与应用生命周期无关。
  2. 任务查询管理:系统查询所有任务、过滤上传任务、过滤下载任务、过滤时间段内任务、过滤前端任务、过滤后台任务、用户查询指定任务信息、用户查询指定隐藏任务信息、系统查询指定任务信息、系统清理指定任务等。
  3. 任务自动恢复:网络条件不满足时任务不启动或者暂停,满足后自动启动或者恢复(需要HTTP服务器支持断点续传)。
  4. 安全隐私保护:包括网络权限检查、普通接口仅操作自己创建的任务、任务信息加密存储、系统接口检查、系统接口查询隐匿任务敏感字段、普通接口查询隐匿任务敏感字段、遍历攻击、DOS、僵尸任务、恶意的静默后台任务、系统管理接口权限等。
  5. 日志:包括调试模式和发布模式。调试模式可打印所有内存修改、磁盘、网络读写、逻辑分支等日志。发布模式下除了导致任务失败、服务异常的日志,其余日志都会关闭。
  6. 任务失败重试:对于不可恢复的原因,直接失败;对于可恢复的原因,网络断开、网络类型不匹配等,不现场重试,任务到等待网络恢复队列;网络超时则就地重试1次,仍网络超时,则立即失败。
  7. 服务按需启停:上传下载服务不随系统自启。应用主动调用任意接口,上传下载服务自动启动。网络连接事件会触发上传下载服务启动。在任务队列中,没有正在处理的任务,或者等待网络恢复的任务,延迟10秒钟,再check一次,仍旧没有的,则通知系统服务框架(SAMGR)可以停止并卸载上传下载服务。在服务退出过程中,新的接口请求可能失败,在客户端检查服务状态、通过重试按需启动。
  8. 通知:任务从第一次开始到最终结束都应该有进度通知。目前采用固定时间间隔触发进度通知,前台任务1秒,后台任务3秒。任务状态的每次变化也要触发进度通知。当任务完成和失败,则触发其专用的进度通知。提供了抑制开关,可以在创建任务时打开,以避免频繁通知。

下载任务的状态迁移流程

使用@ohos.request模块执行下载的任务,具有四种运行状态:初始任务、就绪任务、挂起任务、待网任务、成功任务、失败任务。可以通过create创建任务,start开始任务,pause挂起任务,resume恢复任务,remove移除任务,stop停止任务,任务结果有final-failed任务失败,final-completed下载完成,recoverable-failed重试失败,并支持查询任务状态,具体流程如图一所示:

图一 模块流程图
在这里插入图片描述

常见场景与方案

场景1:低带宽网络上传琐碎文件场景

在网络连接较差,低带宽的网络环境中,HTTP连接的建立耗时可能会大幅提升。这时候进行数据压缩可以加快页面加载速度,并减少HTTP请求数量和移动数据流量。

场景2:处理大量资源的场景

如应用商店、网盘应用等,这类应用通常拥有大体积的文件资源。当用户从暂停或者断网中重新恢复时,如果从头开始上传下载则会额外耗费大量的时间。此时可以采用断点续传方法进行上传下载。

数据压缩

数据压缩是指在应用中对数据进行压缩,以减少存储空间和数据传输量、节省带宽,提高加载速度。数据压缩通常在网络传输和存储方面发挥着重要作用,特别是在处理大量数据或需要频繁传输数据的场景下。

在应用开发中,常见的数据压缩技术分类如下:

  • 有损压缩:仅限图片视频音频等文件适用。通过减少图片视频文件的分辨率,降低音频的音质等手段,以减少文件的大小,来实现减少加载时间和带宽消耗。
  • 无损压缩:对一些零碎文件可以使用@ohos.zlib(Zip模块)来进行打包压缩,减少上传请求次数;对一些大文件可以利用缓存技术,服务器将曾经上传过的大文件MD5码缓存起来,本地在上传前预生成MD5码并传输到服务器进行比对,如果相同则说明服务器存在该文件,可以跳过该文件上传,从而省略重复传输时间。

以从相册批量上传图片为例,介绍大量文件打包无损压缩上传相关技术,下图为相关示例的界面截图:

图二 相册批量上传图片示例图
在这里插入图片描述

以批量上传照片(分辨率为480*640,24位,平均大小50~120KB)为例,在RK设备上测试的结果如下表所示:
在这里插入图片描述

图三 上传数量和耗时对比图表
在这里插入图片描述

由于上传耗时收到网络状态影响偏差较大,结果取的几次测量结果的最小值。但是仍然可以从数据中看出,优化前的耗时基本为线性增长,压缩优化后的耗时在上传文件数量较低时并不明显,还会因为多余的压缩处理影响耗时。不过随着上传的照片数量增多,优化后的耗时和优化之前的耗时差距越来越明显,优化效果越好。

数据压缩的相关示例代码如下:

1.导入相关模块:

import common from '@ohos.app.ability.common';
import fs from '@ohos.file.fs';
import zlib from '@ohos.zlib';

2.创建压缩上传相关类:

class ZipUpload {
  // 创建任务前存放的uri
  private waitList: Array<string> = [];
  // 需要上传的文件uri
  private fileUris: Array<string> = [];
  ...
}

3.建立用于接收图库图片的临时文件夹,并将整个临时文件夹打包添加到待上传list内:

// 文件压缩处理
async zipUploadFiles(fileUris: Array<string>): Promise<void> {
  this.context = getContext(this) as common.UIAbilityContext;
  let cacheDir = this.context.cacheDir;
  let tempDir = fs.mkdtempSync(`${cacheDir}/XXXXXX`);
  // 将图库图片获取的uri放入fileUris中,遍历复制到临时文件夹
  for (let i = 0; i < fileUris.length; i++) {
    let fileName = fileUris[i].split('/').pop();
    let resourceFile: fs.File = fs.openSync(fileUris[i], fs.OpenMode.READ_ONLY);
    fs.copyFileSync(resourceFile.fd, `${tempDir}/${fileName}`, 0);
    fs.closeSync(resourceFile);
  }
  // 文件压缩,将之前生成的临时文件夹内打包到test.zip内
  let options: zlib.Options = {
    level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION,
    memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT,
    strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY
  };
  let data = await zlib.compressFile(tempDir, `${cacheDir}/test.zip`, options);
  // 删除临时文件夹
  fs.rmdirSync(tempDir);
  // 将生成的zip包放到传输队列
  this.waitList.push(`${cacheDir}/test.zip`);
}

断点续传

断点续传功能的实现,不管是应用端还是服务器端都需要用到合理的技术来互相协同。在实际开发中,开发者无需亲自实现断点续传功能,只需对SDK进行合理配置。

在应用端需要用到的技术和API:

  • @ohos.file.fs(文件管理):用于处理文件上传操作,提供了读取文件内容,文件分片和组合的功能。
  • @ohos.file.hash(文件哈希处理):用于实现文件MD5的计算,将计算的MD5值预先传到服务器端进行预处理,实现文件秒传,同时确保传输的准确性和可靠性。
  • @ohos.request(上传下载):用于实现文件上传操作,并支持在上传过程中的断点续传功能。

在服务器端需要用到的技术:

  • 协议需要支持Range:用于在服务器端支持范围请求,方便处理文件上传下载断点续传功能。
  • 文件校验相关逻辑:需要实现校验文件是否有错,确保在传输中断后能够准确恢复并继续传输。

通过结合应用端和服务器端的相关技术,可以共同实现高效且可靠的文件断点续传功能,提供更好的用户体验并确保数据传输的稳定性。

文件上传

对于大文件断点续传上传,本文采用@ohos.request(上传下载)模块中的request.agent任务托管接口,可以自动实现暂停继续重试等操作,无需手动将文件分片和记录上传分片信息。流程图如图四所示:

图四 断点续传上传流程图
在这里插入图片描述

断点续传上传示例代码如下:

1.导入相关模块:

import common from '@ohos.app.ability.common';
import request from '@ohos.request';

1.创建相关上传类:

class Upload {
  // 后台任务
  private backgroundTask: request.agent.Task | undefined = undefined;
  // 创建任务前存放的uri
  private waitList: Array<string> = [];
  ...
}

1.生成MD5码,上传到服务器进行校验:

async checkFileExist(fileUri: string): Promise<boolean> {
  let httpRequest = http.createHttp();
  // 生成md5码
  let md5 = await hash.hash(fileUri, 'md5');
  let requestOption: http.HttpRequestOptions = {
    method: http.RequestMethod.POST,
    extraData: {
      'MD5': md5
    }
  }
  let response = await httpRequest.request('http://XXX.XXX.XXX.XXX/XXXX', requestOption);
  let result = response.result;
  let flag = false;
  ... // 根据服务器返回对应数据判断是否存在
  if (flag) {
    return true;
  } else {
    return false;
  }
}

1.配置Config,创建后台上传任务:

private config: request.agent.Config = {
  action: request.agent.Action.UPLOAD,
  headers: HEADER,
  url: '',
  mode: request.agent.Mode.BACKGROUND,
  method: 'POST',
  title: 'upload',
  network: request.agent.Network.ANY,
  data: [],
  token: 'UPLOAD_TOKEN'
}
...
// 转换uri
private async getFilesAndData(cacheDir: string, fileUris: Array<string>): Promise<Array<request.agent.FormItem>> {
...
}
// 创建文件上传后台任务
async createBackgroundTask(fileUris: Array<string>) {
 // 获取上传url
  this.config.url = 'http://XXX.XXX.XXX.XXX';
  this.config.mode = request.agent.Mode.BACKGROUND;
  let tempData = await this.getFilesAndData(this.context.cacheDir, fileUris);
  // 判断每个文件是否为空
  for (let i = 0; i < tempData.length; i++) {
    let flag = await this.checkFileExist(`${this.context.cacheDir}/${tempData[i].name}`);
    if (!flag) {
      this.config.data.push(tempData[i])
    }
  }
  let isFileExist = await this.checkFileExist(`${this.context.cacheDir}/${this.config.data[0].name}`);
  if (this.config.data.length === 0) {
    return;
  }
  this.backgroundTask = await request.agent.create(this.context, this.config);
}

1.任务开始:

await this.backgroundTask.start();

1.任务暂停:

async pause() {
  if (this.backgroundTask === undefined) {
    return;
  }
  await this.backgroundTask.pause();
}

1.任务继续:

async resume() {
  if (this.backgroundTask === undefined) {
    return;
  }
  await this.backgroundTask.resume();
}

文件下载

对于大文件断点续传下载,也可以直接调用request.agent接口,该接口的断点续传是基于HTTP协议Header里的Range字段实现的,在任务暂停重启的时候,会自动设置Header中的Range字段,无需进行额外的配置。

Range简介

HTTP协议里面的Range字段,官方名称为范围请求,它允许服务器只发送 HTTP
消息的一部分到客户端,可以用来请求部分数据而不是整个资源。

Range的格式通常是Range:
=-,其中表示范围所采用的单位,通常是字节(bytes), 和
表示请求的起始字节和结束字节的位置。

Range语法如下:

// 表示从range-start到文件末尾 Range: =- //
表示从range-start到range-end Range: =- //
可以同时选择多段,用逗号分隔 Range: =-,
- // 示例:表示返回1024 bytes之后的文件 Range: bytes=1024-

服务器收到请求后,正确处理请求会回复206 Partial Content,未正常处理则会回复其他响应码。下表是服务器回复的常见响应码:

服务器响应码常见的原因206 Partial Content服务器收到正常Range请求的响应码,返回部分内容的响应。416 Range
Not Satisfiable所请求的范围不合法,表示服务器错误。200 OK服务器忽略了 Range 首部,返回整个文件。

断点续传下载示例代码如下:

1.导入模块:

import common from '@ohos.app.ability.common';
import request from '@ohos.request';

2.创建下载类:

class Download {
  // 任务存放前的uri
  private waitList: Array<string[]> = [];
  // 下载任务
  private downloadTask: request.agent.Task | undefined = undefined;
  // 后台任务下载列表
  private backgroundDownloadTaskList: Array<request.agent.Task> = [];
  ...
}

3.配置Config,创建后台下载任务:

async createBackgroundTask(downloadList: Array<string[]>) {
  let splitUrl = url.split('//')[1].split('/');
  let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
  let downloadConfig: request.agent.Config = {
    action: request.agent.Action.DOWNLOAD,
    url: url,
    method: 'POST',
    title: 'download',
    mode: request.agent.Mode.FOREGROUND, // 必须是后台任务才能续传
    network: request.agent.Network.ANY,
    saveas: `./${folder}/${splitUrl[splitUrl.length-1]}`,
    overwrite: true
  }
  this.downloadTask = await request.agent.create(context, downloadConfig);
  if (this.backgroundDownloadTaskList.findIndex(task => task.config.url === downTask.config.url) === -1) {
    this.backgroundDownloadTaskList.push(downTask);
  }
}

4.任务开始:

...
await downTask.start();
...

5.任务暂停:

async pause() {
  if (this.backgroundDownloadTaskList.length === 0) {
    return;
  }
  this.backgroundDownloadTaskList.forEach(async task => {
    await task.pause();
  })
}

6.任务继续:

async resume() {
  if (this.backgroundDownloadTaskList.length === 0) {
    return;
  }
  this.backgroundDownloadTaskList.forEach(async task => {
    await task.resume();
  })
}

7.任务停止:

async deleteAllBackTasks() {
  if (this.backgroundDownloadTaskList.length > 0) {
    this.backgroundDownloadTaskList.forEach(async task => {
      await request.agent.remove(task.tid);
    })
    this.backgroundDownloadTaskList = [];
  }
}

如果大家还没有掌握鸿蒙,现在想要在最短的时间里吃透它,我这边特意整理了《鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程》以及《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

OpenHarmony APP开发教程步骤:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

《鸿蒙开发学习手册》:

如何快速入门:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.基本概念
2.构建第一个ArkTS应用
3.……

在这里插入图片描述

开发基础知识:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

鸿蒙生态应用开发白皮书V2.0PDF:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

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

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

相关文章

使用vite从头搭建一个vue3项目(三)vite.config.js配置

目录 一、声明环境变量配置文件二、vite.config.js基础配置1、defineConfig()、loadEnv()2、plugins配置项3、server配置项4、resolve配置项5、css配置项6、build配置项 三、vite.config.js配置完整代码 VITE版本&#xff1a;v5.2.8 一、声明环境变量配置文件 在根目录下新建…

react 安装教程

1、安装脚手架 脚手架主要分为三个部分&#xff1a; react:顶级库。 react-dom&#xff1a;运行环境。 react-scripts&#xff1a;运行和打包react应用程序的脚本和配置。 npm install -g create-react-app 2、创建项目 #查看版本号 create-react-app -V #创建项目 creat…

李廉洋:4.23黄金休市之后大幅下跌,原油小幅度上涨。走势分析!

今年以来推动金价上涨的因素是亚洲的需求&#xff0c;很可能来自各国央行。最近又有零售买盘和一些金融买盘作为补充。目前的问题是&#xff0c;不断上升的债券收益率正在争夺资金。美国2年期国债的收益率接近5%&#xff0c;在美联储降息导致收益率开始下降之前&#xff0c;这仍…

13.Nacos简介,下载,安装,启动-windows

Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud的一个组件。 相比Eureka功能更加丰富&#xff0c;服务注册与发现和分布式配置。 Nacos下载地址&#xff1a; https://github.com/alibaba/nacos windows下载nacos-server-1.4.1.zip文件 nacos是基于java语言实现的&…

iStat Menus for Mac:强大的系统监控工具

iStat Menus for Mac是一款功能强大的系统监控工具&#xff0c;专为Mac用户设计&#xff0c;旨在帮助用户全面了解电脑的运行状态&#xff0c;提高电脑的性能和稳定性。 iStat Menus for Mac v6.73 (1239)中文版下载 该软件可以实时监测CPU使用率、内存占用、网络速度、硬盘活动…

力扣HOT100 - 25. K 个一组翻转链表

解题思路&#xff1a; class Solution {public ListNode reverseKGroup(ListNode head, int k) {ListNode dum new ListNode(0, head);ListNode pre dum;ListNode end dum;while (end.next ! null) {for (int i 0; i < k && end ! null; i) {end end.next;}if …

思科 Packet Tracer 实验八 DHCP基本配置(以路由为中继)

一、实验目的 了解思科网络设备的配置基本特点及 IOS 命令基本操作方法 了解DHCP的工作原理及基本配置 二、实验过程 1) 实验拓扑如下&#xff1a; 2&#xff09;由于使用DHCP‘协议动态配置ip&#xff0c;所以除了DHCP服务器和路由器接口外其他的主机&#xff0c;服务器的i…

Spring之AOP编程

一.静态代理设计模式 1.为什么需要代理设计模式&#xff1f; 在JavaEE开发中&#xff0c;哪个层次最为重要&#xff1f; DAO层->Service层->Controller层。最重要的是Service层 Service层包含了哪些代码&#xff1f; 1.核心功能&#xff1a;业务运算DAO调用 2.额外…

必应搜索广告与谷歌搜索广告对比那个更好?

搜索引擎广告作为企业获取潜在客户的重要渠道之一&#xff0c;其效果直接关系到营销策略的成功与否。两大搜索引擎巨头——谷歌&#xff08;Google&#xff09;和必应&#xff08;Bing&#xff09;各自提供了广告平台&#xff0c;即谷歌广告&#xff08;Google Ads&#xff09;…

MSR是个什么寄存器

MSR 这种寄存器专门用于调试、程序执行跟踪、计算机性能监控、简化软件编程、电源控制等等各种实验性功能。 什么是 MSR MSR 的概念是不易理解&#xff0c;所以这一节只说一些 MSR 的外在&#xff0c;比如形容和指令等&#xff0c;然后展开说说&#xff0c;看完整篇文章你应该…

向媒体投稿有了好方法财政单位信息宣传工作简单又轻松

当我初涉财政单位的信息宣传岗位,肩负起对外展示单位风采、传播政策信息的重要职责时,我深刻体验到了投稿之路的艰辛曲折。初期,对于如何有效对接媒体并成功发表稿件,我感到一片茫然,仿佛置身于浩瀚的信息海洋中,无从下手。 那时,我的工作日常就是广泛搜集各类媒体的联系方式,特…

稀碎从零算法笔记Day56-LeetCode:组合总和 Ⅳ

题型&#xff1a;DP、数组 链接&#xff1a;377. 组合总和 Ⅳ - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一个由 不同 整数组成的数组 nums &#xff0c;和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的…

数据结构系列-堆排序

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 昨天我们实现的堆的搭建&#xff0c;我们今天实现以下堆的排序&#xff0c; 堆的排序的最大的优点就是提高的效率&#xff0c;减小了时间复杂度&#xff0c;在这个里面我们有一个…

C++ 并发编程指南(11)原子操作 | 11.5、内存模型

文章目录 一、C 内存模型1、为什么需要内存模型&#xff1f;2、happens-before和synchronize-with两个关键概念2.1、happens-before2.2、synchronize-with2.3、总结 前言 C 11标准中最重要的特性之一&#xff0c;是大多数程序员都不会关注的东西。它并不是新的语法特性&#xf…

系统思考—业务复盘

今日的JSTO——《业务复盘》中&#xff0c;赵海懿老师的分享启发了我深度反思。她提到的两句话特别引人思考&#xff1a; 1、学校里学到的最重要的东西&#xff0c;就是“最重要的东西在学校里学不到”。 2、学习型组织不只是组织学习。 这些话提醒我们&#xff0c;真正的学习…

区块链钱包开发指南: 探究区块链钱包开发涉及

区块链钱包是连接用户与区块链网络的重要工具&#xff0c;它们不仅提供了安全的存储和管理数字资产的功能&#xff0c;还允许用户进行交易和与区块链上的智能合约进行互动。本文将探究区块链钱包开发涉及的关键方面和技术要点。 1. 区块链钱包类型 区块链钱包可以分为以下几种…

Unity中的UI系统之UGUI

目录 概述UGUI基础——六大基础组件六大基础组件概述Canvas画布组件CanvasScaler画布缩放控制器组件必备知识恒定像素模式缩放模式恒定物理模式3D模式 Graphic Raycaster图形射线投射器EventSystem和Standalone Input ModuleRectTransform UGUI基础——三大基础控件Image图像控…

JS - 以工厂模式和原型模式方式建造对象、JS的垃级回收机制、数组的使用

创建对象的方式 使用工厂方法来建造对象 在JS中我们可以通过以下方式进行创建对象&#xff1a; var obj {name:"孙悟空",age:18,gender:"男",sayName:function(){alert(this.name);}};var obj2 {name:"猪八戒",age:28,gender:"男",…

【第4讲】XTuner 微调 LLM:1.8B、多模态、Agent

目录 1 简介2 基础知识2.1 finetune简介2.2 xtuner简介2.2.1 技术架构2.2.2 快速上手xtuner 2.3 8GB显存玩转LLM&#xff08;intern1.8b&#xff09;2.3.1 flash attention vs deepspeed zero2.3.2 相关版本更新和使用 2.4 多模态LLM2.4.1 多模态LLaVA基本原理简介2.4.2 快速上…

Linux的学习之路:18、进程间通信(2)

摘要 本章主要是说一下命名管道和共享内存 目录 摘要 一、命名管道 1、创建一个命名管道 2、匿名管道与命名管道的区别 3、命名管道的打开规则 4、代码实现 二、system V共享内存 1、共享内存 2、共享内存函数 三、代码 四、思维导图 一、命名管道 1、创建一个命…