[操作系统]I/O管理 缓冲区/SPOOLing

I/O管理

基本任务:完成用户提出的I/O请求,提高I/O效率,提高I/O设备的利用率

主要功能:缓冲区管理,设备分配,设备处理,虚拟设备,实现设备独立性

I/O管理概述

I/O管理目标

  1. 提供统一界面、方便用户使用

    使用逻辑操作和逻辑设备名掩盖设备的物理细节。
    程序对设备的独立性:在源程序和目标程序中都使用设备符号名(逻辑设备名);提供设备管理与文件系统的统一接口;向程序提供设备重定向功能。

  2. 发挥系统的并行性,提高I/O设备使用效率。
    采用各种软硬结合的技术使设备、CPU、用户程序、人这四者达到最高程度的并行
    采用的技术有:中断技术、缓冲技术、设备共享和假脱机技术。

  3. 实现设备的正确、安全使用——设备保护

    技术:掩盖细节的高级接口;命名与权限管理;只有特权指令才能使用设备硬件接口。

I/O管理功能

  1. 缓冲区管理
    计算机系统中各个部件速度的差异很大。中央处理机的速度以纳秒计,外部设备的处理速度则以毫秒甚至秒计。在不同时刻,系统各部分的负荷也常常很不均衡。为充分发挥并行性,引入缓冲技术。

  2. 外围设备的分配
    按照设备的类型 (独享、共享或虚拟) 和系统中所采用的分配算法,决定把一个I/O设备分配给哪一个要求该类设备的进程。

    在大、中系统中,分配设备的同时,还应分配相应的控制器和通道,以保证I/O设备与CPU之间有传递信息的通路;凡未分配到所需设备或控制器或通道的进程,应放入相应的等待队列。设备分配程序就是用来实现这一功能的。

  3. 设备处理
    设备处理程序又叫设备驱动程序。

  4. 虚拟设备及实现设备独立性

I/O设备

Input/Output (输入输出)

就是可以将数据输入到计算机,或者可以接收计算机输出数据的外部设备,属于计算机硬件。

I/O设备分类

按使用特性

在这里插入图片描述

数据传输速度慢人机交互设备:鼠标,键盘,打印机等

数据传输速度快 存储设备:移动硬盘,光盘

用于网络通信 网络通信设备:调制解调器

按传输速率

在这里插入图片描述

低速设备: 每秒为几到几百字节 鼠标,键盘等

中速设备:传输速率为每秒数千至上万字节 如行式打印机、激光打印机

高速设备:传输速度为每秒数千字节至兆字节的设备 如磁盘、光盘、以太网、图形显示设备

按信息交换的单位分类

在这里插入图片描述

块设备:数据传输的基本单位是块 如磁盘等 传输速率较高,可寻址,适合DMA,即对该设备可随机地读/写任一块

字符设备:数据传输的基本单位是字节 鼠标键盘等 传输速率较慢,不可寻址,在输入/输出时常采用中断驱动方式

I/O控制器

I/O设备由机械部件,电子部件(I/O控制器,设备控制器)组成。

机械部件:用于执行具体I/O操作。

电子部件:通常是一块插入主板扩充槽的印刷电路板。

CPU无法直接控制I/O设备的机械部件,因此I/O设备需要一个电子设备作为CPU和I/O设备机械部件之间的中介,用于实现CPU对设备的控制。

I/O控制器即设备控制器。CPU可控制I/O控制器,又由I/O控制器来控制设备的机械部件。

设备控制器的功能

在这里插入图片描述

  1. 接收识别CPU发出的命令

    设置控制寄存器来存放命令和数据

  2. 向CPU报告设备的状态

    设置状态寄存器用于记录I/O设备的当前状态。

  3. 数据交换

    设置数据寄存器,用于CPU与控制器与设备之间的数据传输。

  4. 地址识别

    类似于内存的地址,为了区分设备控制器中的各个寄存器,也需要给各个寄存器设置一个特定的地址。I/O控制器通过CPU提供的地址,来判断CPU读/写的是哪个寄存器。

I/O控制器的组成
  1. CPU与控制器的接口

    用于实现CPU与控制器之间的通信。CPU通过控制线发出命令,通过地址线指明要操作的设备,通过数据线来取出(输入)数据,放出(输出)数据。

  2. I/O逻辑

    负责接收和识别CPU的各种命令(如地址译码),并负责对设备发出命令

  3. 控制器与设备的接口

    用于实现控制器与设备之间的通信。

在这里插入图片描述

注意

一个I/O控制器可能对应多个设备

数据寄存器,控制寄存器,状态寄存器可能有多个

有些计算机会让这些寄存器占用地址的一部分,称为内存映象

另一些计算机采用I/O专用地址,即寄存器独立编址

寄存器编址方式
内存映象

控制器中的寄存器与内存地址统一编址

在这里插入图片描述

*优点:*简化了指令。可以采用对内存进行操作的指令来对控制器进行操作

寄存器独立编址

控制器中的寄存器单独编址。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vA8vtluO-1598687010874)(D:\StudyData\Notes[其他]计算机通用知识\OSpics\image-20200828111158666.png)]

*缺点:*需要设置专门的指令来实现对控制器的操作,不仅要指明寄存器的地址,还要指明控制器的编号。

I/O控制方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y6gzgfOO-1598687010875)(D:\StudyData\Notes[其他]计算机通用知识\OSpics\image-20200828111742432.png)]

程序直接控制方式

Key word:轮询

  1. 完成一次读/写操作的流程(以读操作为例)

在这里插入图片描述

  1. CPU干预的频率

    很频繁,I/O操作开始之前、完成之后需要CPU的介入,并且在等待I/O完成的过程中CPU需要不断地轮询检查

  2. 数据传输单位

    每次读/写一个

  3. 数据流向

    读操作(数据输入):I/O设备 -> 内存

    每个字的读写都需要CPU的帮助

  4. 主要优缺点

    优点:实现简单,在读写指令之后,加上实现循环检查的一系列指令即可

    缺点:CPU和I/O设备只能串行工作,CPU需要一直轮询检查,长期处于忙等状态,CPU利用效率低。

中断驱动方式

引入中断机制。由于I/O设备速度很慢,因此在CPU发出读写命令后,可将等待I/O的进程阻塞,先切换到别的进程执行。当I/O完成后,控制器会向CPU发出一个中断信号,CPU检测到中断信号后,会保存当前进程的运行环境信息,转去执行中断处理程序处理该中断。处理中断的过程中,CPU从I/O控制器读入一个字的数据传送到CPU寄存器,再写入主存。接着,CPU恢复等待I/O的进程的运行环境,然后继续执行

完成CPU与I/O设备并行执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wus41Sch-1598687010877)(D:\StudyData\Notes[其他]计算机通用知识\OSpics\image-20200828113254252.png)]

注意:

  1. CPU会在每个指令周期的末尾检查中断;

  2. 中断处理过程中需要保存,恢复进程的运行环境;

    这个过程需要一定的时间开销。可见,如果中断发生的频率过高,也会降低系统性能

  3. CPU的干预频率

    每次I/O操作开始之前,完成之后需要CPU介入。

    等待I/O完成的过程中CPU可以切换到别的进程执行

  4. 数据的传送单位

    每次读写一个

  5. 数据的流向

    读操作(数据输入):I/O设备->CPU->内存

    写操作(数据输出):内存->CPU->内存

  6. 主要优缺点

    优点:CPU与I/O设备可并行工作,CPU利用率明显提升。

    缺点:每个字在I/O设备与内存之间的传输,都需要经过CPU。而频繁的中断处理会消耗较多的CPU时间

DMA方式

直接存储器存取。主要用于块设备(I/O)控制

改进:

  1. 数据的传输单位是块
  2. 数据的流向直接从设备写入内存,或者内存写入设备,无需CPU作为中介。
  3. 仅在传送一个或多个数据块的开始和结束时,才需要CPU的干预。
    阿

CPU需要指明此次要进行的操作种类,读入数据数量,数据存放位置,以及数据位于外存哪些位置等。

控制器根据CPU提出的要求完成数据的读/写工作,整块数据的传输完成后,才向CPU发出中断信号。

  1. CPU干预的频率

    仅在传送一个或多个数据块的开始和结束时,才需要CPU干预

  2. 数据传输的单位

    每次读/写一个或多个块(每次读写的只能是连续的多个块,且这些块读入内存后在内存中也必须是连续的)

  3. 数据流向

    读操作(数据输入):I/O设备->内存

    写操作(数据输出):内存->内存

  4. 主要的优缺点

    优点:数据传输以为单位,CPU介入频率进一步降低。数据的传输不在需要经过CPU再写入内存,数据传输效率进一步增加。CPU与I/O设备的并行性得到提升。

    缺点:CPU每发出一条I/O指令,只能读/写一个或多个连续的数据块。

    如果要读写多个离散存储的数据块,或者要将数据分贝写到不同的内存区域时,CPU要分别发出多条I/O指令,进行多次中断才能完成。

DMA控制器

在这里插入图片描述

DMA控制器按字读入数据,暂存到DR中,达到块数后存入内存。

I/O通道方式

一种硬件,弱鸡CPU,通道可以识别并执行一系列通道指令

在这里插入图片描述

与CPU相比,通道可以执行的指令很单一,并且通道程序是存放在主机内存中的,也就是说通道和CPU共享内存

在这里插入图片描述

  1. CPU干预频率

    极低,通道会根据CPU的指示执行相应的通道程序,只有完成一组数据块的读/写后才需要发出中断信号,请求CPU干预。

  2. 数据传送的单位

    每次读/写一组数据块

  3. 数据流向(在通道的控制下进行)

    读操作(数据输入):I/O设备->内存

    写操作(数据输出):内存->内存

  4. 主要优点与缺点

    优点:CPU,I/O设备,通道可以并行工作,资源利用率高

    缺点:实现复杂,需要专门的通道硬件支持。

总结

在这里插入图片描述

一个通道可以控制多个I/O控制器,一个I/O控制器可以控制多个I/O设备

I/O软件层次结构(记住顺序)

用独驱中

直接涉及到硬件具体细节,且与中断无关的操作必然在设备驱动程序层完成;未涉及硬件的,对各种设备都需要进行的管理工作都是在设备独立性软件层完成的

越上面的层次越接近用户,越下层的越接近硬件,每一层都会利用其下层提供的服务,实现某些功能,并屏蔽实现的具体细节,向高层提供服务。

在这里插入图片描述

用户层

实现了与用户交互的接口。用户可直接使用该层提供的,与I/O操作相关的库函数对设备进行操作。

该层将用户请求翻译成格式化的I/O请求,并通过系统调用请求操作系统内核服务。

设备独立性软件

又称为设备无关性软件。与设备的硬件特性无关的功能几乎都于该层实现。

主要功能
  1. 向上层提供统一的调用接口

  2. 设备的保护

    类似于对文件的保护。设备被看做一种特殊的文件

  3. 差错处理

  4. 设备的分配与回收

  5. 数据缓冲区处理

    可以通过缓冲技术屏蔽设备之间的数据交换单位大小与传输速度的差异。

  6. 建立逻辑设备名到物理设备名之间的映射关系,根据设备类型选择调用相应的驱动程序

    设备独立性软件需要通过逻辑设备表(LUT ,Logical Unit Table)来确定逻辑设备对应的物理设备,并找到该设备对应的设备驱动程序

在这里插入图片描述

操作系统可采用两种方式管理逻辑设备表LUT

  1. 整个系统设置一张LUT,意味着所有用户不能使用相同的逻辑设备名,因此这种方式只适用于单用户操作系统。
  2. 每个用户设置一张LUT,各个用户使用的逻辑设备名可以重复,适用于多用户操作系统。系统会在用户登录时为其建立一个用户管理进程,而ULT就存放在用户管理进程的PCB中。
设备驱动程序

不同设备的硬件特性不同,导致需要不同的设备驱动程序。

主要负责对硬件设备的具体控制,将上层发出的一系列命令,转换为设备可以执行的一系列操作。包括设置设备寄存器,检查设备状态等

中断处理程序

当I/O任务完成时,I/O控制器会发送一个中断信号,系统会根据中断信号类型找到对应的中断处理程序并执行。

中断处理程序的处理流程如下:

在这里插入图片描述

中断处理程序也会直接和硬件交涉

I/O核心子系统

I/O核心子系统概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-06Wh204v-1598687010884)(D:\StudyData\Notes[其他]计算机通用知识\OSpics\image-20200828143823134.png)]

I/O调度

使用某种算法确定一个好的顺序来处理各个I/O请求

设备保护

将设备看做一种特殊的文件,每个设备对应一个FCB。类似文件保护

I/O软件

I/O系统必须采用某种技术使I/O设备可以按统一的标准方式对待。

采用的方式有:抽象、包装与软件分层

可以从不同的I/O设备中抽象出一些通用类型。每个通用类型都可以通过一组标准函数(即接口)来访问。具体的差别被内核模块(设备驱动程序)所封装。

不同设备有自己的驱动程序,但提供了一组标准接口。设备驱动程序层为内核I/O子系统隐藏设备控制器之间的差异,从而简化了OS开发人员的任务,也有利于硬件制造商。

每种OS都有自己的设备驱动程序接口。故一个特定设备可能有多种设备驱动程序。

而I/O系统调用又为上层应用程序包装了硬件细节。

应有的目标
  1. 与具体设备无关
    程序员只要知道如何使用I/O硬件资源完成所需的操作,而无需了解设备的有关具体实现细节。
    I/O软件屏蔽设备的具体细节,向高层软件提供抽象的逻辑设备,并完成逻辑设备到物理设备的映射。
  2. 统一命令
    系统中对各类不同物理设备采取预先设计的、统一的逻辑名称,所有软件以逻辑名访问设备,可能同一逻辑名在不同情况下对应不同物理设备。
  3. 对错误的处理
    I/O错误尽可能由接近硬件的低层软件处理,不让高层软件感知。
  4. 缓冲技术
  5. 设备的分配和释放
  6. I/O控制方式
    对于不同的设备选择不同的I/O控制方式(程序I/O、中断、DMA、通道)。

假脱机技术

在这里插入图片描述

实际于用户层实现

在联机情况下实现的同时外围操作称为SPOOLing,也叫假脱机。

脱机技术介绍

缓解了CPU与慢速I/O设备的速度矛盾。即使CPU在忙碌,也可以提前将数据输入到磁带,即使慢速的输出设备正在忙碌,也可以提前将数据输出到磁带。

批处理阶段引入脱机输入/输出技术,即无需主机控制的输入输出操作。

在这里插入图片描述

假脱机技术

SPOOLing技术是用软件的方式模拟脱机技术。

可以把一台物理设备虚拟成逻辑上的多台设备,可将独占式设备该着成共享设备。

SPOOLing系统组成如下:

在这里插入图片描述

在磁盘上开辟出两个存储区 – 输入井和输出井。

输入井 模拟脱机输入时的磁带,用于收容I/O设备输入的数据。

输出井 模拟脱机输出时的磁带,用于收容用户进程输出的数据。

在输入进程的控制下,输入缓冲区用于暂存从输入设备输入的数据,之后再转存到输入井中。

在输出进程的控制下,输出缓冲区用于暂存从输出井送来的数据,之后再传送到输出设备上。

输入输出缓冲区是在内存中的缓冲区

共享打印机原理分析

独占式设备 只允许各个进程串行使用的设备。一段时间只能满足一个进程的请求。

共享设备 允许各个进程串行使用的设备。(宏观上同时使用,微观上可能是交替使用)。可同时满足多个进程的使用请求。

在这里插入图片描述

当多个用户进程提出输出打印的请求时,系统会答应他们的请求,单不是真将打印机分配给他们,而是由假脱机管理进程为每个进程做两件事:

  1. 在磁盘输出井中为进程申请一个空闲缓冲区(缓冲区位于磁盘上),并将要打印的数据送入其中。
  2. 为用户进程申请一张空白的打印请求表,并将用户的打印请求填入表中(其实就是用来说明用户的打印数据存放位置等信息),再将该表挂到假脱机文件队列上。

当打印机空闲时,输出进程会从文件队列的队头取出一张打印请求表,并根据表中的要求将要打印的数据从输出井传送到输出缓冲区,再输出到打印机进行打印。用这种方式可以依次处理完全部的打印任务。

虽然仅有一台打印机,但每个进程提出打印请求时,系统都会为在输出井中的为其分配一个存储区(相当于分配了一个逻辑设备),使每个用户进程都觉得自己的在独占一台打印机,从而实现对打印机的共享。

设备的分配与回收

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y3j8siDX-1598687010887)(D:\StudyData\Notes[其他]计算机通用知识\OSpics\image-20200828195301923.png)]

设备分配时应考虑的因素
  1. 设备的固有属性

    独占设备,一个时间段只能分配给一个进程(如打印机)

    共享设备,可同时分配给多个进程使用(如磁盘),各进程往往是宏观上同时共享使用设备,而微观上交替使用。

    虚拟设备,使用SPOOLing技术将独占设备改造成虚拟的共享设备,可同时分配给多个进程使用(如采用SPOOLing技术实现的共享打印机)

  2. 设备分配算法

  3. 设备分配中的安全性

    安全分配方式:为进程分配一个设备后就将进程阻塞,本次I/O完成后才将进程唤醒。

    优点:破坏了请求与保持条件,不会死锁

    缺点:对于一个进程而言,CPU和I/O设备只能串行工作

    不安全I/O方式:进程发出I/O请求后,系统为其分配I/O设备,进程可继续执行,之后还可以发出新的I/O请求。只有某个I/O请求得不到满足后才将进程阻塞。

    优点:进程的计算任务和I/O任务可以并行处理,是进程迅速推进

    缺点:有可能发生死锁(死锁避免,死锁检测和解除)

静态分配和动态分配

静态分配:进程运行前为其分配全部资源,运行结束后归还资源 破坏请求与保持条件

动态分配:进程运行过程中动态申请设备

设备管理中的数据结构

在这里插入图片描述

一个通道可以控制多个设备控制器,每个设备控制器可以控制多个设备。

设备控制表 DCT:系统为每个设备设置一张DCT,用于记录设备情况。

在这里插入图片描述

进程管理中曾经提到系统会根据阻塞原因不同将进程PCB挂到不同的阻塞队列中

控制器控制表 COCT:每个设备对应一张COCT。操作系统根据COCT的信息对控制器进行操作和管理。

在这里插入图片描述

通道控制表 CHCT:每个通道对应一张CHCT。操作系统根据CHCT的信息对通道进行操作和管理。

在这里插入图片描述

系统设备表 SDT:记录了系统中全部设备的情况,每个设备对应一个表目。

在这里插入图片描述

在这里插入图片描述

设备分配的步骤
未优化步骤
  1. 根据进程请求的物理设备名查找SDT(物理设备名是进程请求分配设备时提供的参数)

在这里插入图片描述

  1. 根据SDT找到DCT,若设备忙碌则将进程PCB挂到设备等待队列中,不忙碌则将设备分配给进程
    在这里插入图片描述

  2. 根据DCT找到COCT,若控制器忙碌则将进程PCB挂到控制器等待队列中,不忙碌则将控制器分配给进程。
    在这里插入图片描述

  3. 根据COCT找到CHCT,若通道忙碌则将进程PCB挂到通道等待队列中,不忙碌则将通道分配给进程。
    在这里插入图片描述

只有设备,控制器,通道三者都分配成功时,这次设备分配才算成功,之后便可启动I/O设备进行数据传送

缺点:

  1. 用户编程时必须使用 物理设备名,底层细节对用户不透明,不方便编程
  2. 若更换物理设备,则程序无法运行
  3. 若进程请求的物理设备正在忙碌,则即使系统中还有同类型的设备,进程也必须阻塞等待。
优化后的设备分配

建立逻辑设备名与物理设备名的映射机制,用户编程时只需提供逻辑设备名。

  1. 根据进程请求的逻辑设备名查找SDT(用户编程时提供的逻辑设备名就是设备类型)
  2. 查找SDT,找到用户进程指定类型、并且空闲的设备,将其分配给进程。操作系统就是在逻辑设备表LUT中新增一个表项
  3. 根据DCT找到COCT,若控制器忙碌则将进程PCB挂到控制器等待队列中,不忙碌则将控制器分配给进程。
  4. 根据COCT找到CHCT,若通道忙碌则将进程PCB挂到通道等待队列中,不忙碌则将通道分配给进程。

在这里插入图片描述

逻辑设备表LUT建立了逻辑设备名与物理设备名之间的映射关系
在这里插入图片描述

逻辑设备表设置方法
  1. 整个系统只有一张LUT:各用户所用的逻辑设备名不允许重复,适用于单用户的操作系统
  2. 每个用户一张LUT:不同用户的逻辑设备名可重复,适用于多用户操作系统

缓冲区管理

缓冲区是一个存储区域,可以由专门的硬件寄存器组成,也可利用内存作为缓冲区

使用硬件作为缓冲区的成本较高,容量也较小,一般仅用于对速度要求非常高的场合(如存储器管理中所用的联想存储器,由于对页表的访问频率极高,因此使用速度很快的联想寄存器来存放页表项的副本)

一般使用内存作为缓冲区,设备独立性软件的缓冲区管理就是要组织管理好这些缓冲区。

引入缓冲区的原因
  1. 处理数据的生产者和消费者速度不匹配。如从调制解调器上收到文件并保存到硬盘上。

  2. 协调传输数据大小不一致的设备。

    如计算机网络上,发送方消息被分成若干包,接收方在缓冲区中重组数据。

  3. 减少对CPU的中断频率
    例如:速率为9.6Kb/s的数据通信,每100us中断CPU一次,若设置8位缓冲,可使CPU被中断的频率降低为原来的1/8,再设置8位寄存器,使CPU中断响应的时间放宽到800us。

  4. 提高CPU和I/O设备之间的并行性

缓冲区作用

以内存作为缓冲区

  1. 缓和CPU与I/O设备之间速度不匹配的矛盾
  2. 减少对CPU的中断频率,放宽对CPU中断响应时间的限制
  3. 解决数据粒度不匹配的问题
  4. 提高CPU与I/O设备之间的并行性

在这里插入图片描述

单缓冲

假设某用户进程要求某种块设备读入若干块的数据。若采用单缓冲,操作系统会在主存中为其分配一个缓冲区(若题中没有说明,一个缓冲区的大小就是一个块)

当缓冲区数据非空时,不能往缓冲区冲入数据,只能从缓冲区把数据传出;当缓冲区为空时,可以往缓冲区冲入数据,但必须把缓冲区冲满后,才能从缓冲区把数据传出。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L91TgovI-1598687010897)(D:\StudyData\Notes[其他]计算机通用知识\OSpics\image-20200828205455070.png)]

初始状态:工作区满,缓冲区空

假设T>C

在这里插入图片描述

假设T<C

在这里插入图片描述

双缓冲

操作系统会在主存中为其分配两个缓冲区(若题目没有特别说明,一个缓冲区的大小就是一个块)

双缓冲题目中,假设初始状态为:工作区空,其中一个缓冲区满,另一个缓冲区空

假设T>C+M

在这里插入图片描述

假设T<C+M

在这里插入图片描述

结论:采用双缓冲策略,处理一个数据块的平均耗时为Max(T,C+M)

使用单缓冲和双缓冲在通信时区别

两台机器之间通信时,可以配置缓冲区用于数据的发送和接收

在这里插入图片描述

显然,两个相互通信的机器只设置单缓冲区,在任一时刻只能实现数据的单向传输。

在这里插入图片描述

若两个相互通信的机器设置双缓冲区,则同一时刻可以实现双向的数据传输。

管道通信中的管道其实就是缓冲区。要实现数据的双向传输,必须设置两个管道

循环缓冲

将多个大小相等的缓冲区链接成一个循环队列

下图中,橙色表示已经充满数据的缓冲区,绿色表示空缓冲区。

在这里插入图片描述

缓冲池

由系统中共用的缓冲区组成。这些缓冲区按使用情况可分为:空缓冲队列,装满输入数据的缓冲队列(输入队列),装满输出数据的缓冲队列(输出队列)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-96cSlPxs-1598687010902)(D:\StudyData\Notes[其他]计算机通用知识\OSpics\image-20200828213534145.png)]

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fire-From

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值