队列 -- fifo

【C# 数据结构】队列 FIFO 队列和FIFO是什么关系?队列是一种数据结构。FIFO是队列需要遵循的基本原则:First-In, First-Out。或者说FIFO是队列的基本特性!C#中有个类叫做Queue,就是实现了队列这种数据结构的类,它遵循FIFO这个原则。 阅读详情

linux 内核通用队列称为 kfifo.  定义于<linux/kfifo.h>中

linux 的 kfifo 和多数其他队列一样,也提供了两个主要函数,enqueue(入队列) 和 dequeue(出队列)

kfifo 对象 维护了两个偏移量,入口偏移 和 出口偏移。

入口偏移 指下一次入队列时的位置

出口偏移 指下一次出队列的位置。

出口偏移 总是小于等于 入口偏移,否则就意味着要出队列的元素根本没有入队列。

1. 创建队列:

a. kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask) : 动态创建, (常用),

该函数创建并初始化一个大小为size的kfifo. gfp_mask  用来标识分配队列。

/**
 * kfifo_alloc - allocates a new FIFO internal buffer
 * @fifo: the fifo to assign then new buffer
 * @size: the size of the buffer to be allocated, this have to be a power of 2.
 * @gfp_mask: get_free_pages mask, passed to kmalloc()
 *
 * This function dynamically allocates a new fifo internal buffer
 *
 * The size will be rounded-up to a power of 2.
 * The buffer will be release with kfifo_free().
 * Return 0 if no error, otherwise the an error code
 */
int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask)
{
	unsigned char *buffer;

	/*
	 * round up to the next power of 2, since our 'let the indices
	 * wrap' technique works only in this case.
	 */
	if (!is_power_of_2(size)) {  //size必须是2的指数次幂
		BUG_ON(size > 0x80000000);
		size = roundup_pow_of_two(size); //如果不是整成是~
	}

	buffer = kmalloc(size, gfp_mask);
	if (!buffer) {
		_kfifo_init(fifo, NULL, 0);
		return -ENOMEM;
	}

	_kfifo_init(fifo, buffer, size); //初始化fifo

	return 0;
}

static void _kfifo_init(struct kfifo *fifo, void *buffer,
		unsigned int size)
{
	fifo->buffer = buffer;
	fifo->size = size;

	kfifo_reset(fifo);
}

/**
 * kfifo_reset - removes the entire FIFO contents
 * @fifo: the fifo to be emptied.
 */
static inline void kfifo_reset(struct kfifo *fifo)
{
	fifo->in = fifo->out = 0;
}

例:

struct kfifo fifo;

int ret;

ret = kfifo_alloc(&fifo, PAGE_SIZE, GFP_KERNEL);

if(ret)

    return ret;

//fifo 现在是一个大小为PAGE_SIZE的队列

b. kfifo_init(struct kfifo *fifo, void *buffer, unsigned int size):

该函数创建并初始化一个kfifo,它将使用 由 buffer 指向的 大小为size 的内存

/**
 * kfifo_init - initialize a FIFO using a preallocated buffer
 * @fifo: the fifo to assign the buffer
 * @buffer: the preallocated buffer to be used.
 * @size: the size of the internal buffer, this has to be a power of 2.
 *
 */
void kfifo_init(struct kfifo *fifo, void *buffer, unsigned int size)
{
	/* size must be a power of 2 */
	BUG_ON(!is_power_of_2(size)); //size必须是2的指数次幂

	_kfifo_init(fifo, buffer, size);
}
EXPORT_SYMBOL(kfifo_init);

c. 静态创建kfifo,(不大常用):

DECLARE_KFIFO(name, size) --- 将创建一个名字为name,大小为size的kfifo对象。

/**
 * DECLARE_KFIFO - macro to declare a kfifo and the associated buffer
 * @name: name of the declared kfifo datatype
 * @size: size of the fifo buffer. Must be a power of two.
 *
 * Note1: the macro can be used inside struct or union declaration
 * Note2: the macro creates two objects:
 *  A kfifo object with the given name and a buffer for the kfifo
 *  object named name##kfifo_buffer
 */
#define DECLARE_KFIFO(name, size) \
union { \
	struct kfifo name; \
	unsigned char name##kfifo_buffer[size + sizeof(struct kfifo)]; \
}
 INIT_KFIFO(name) --- 初始化kfifo

/**
 * INIT_KFIFO - Initialize a kfifo declared by DECLARE_KFIFO
 * @name: name of the declared kfifo datatype
 */
#define INIT_KFIFO(name) \
	name = __kfifo_initializer(sizeof(name##kfifo_buffer) - \
				sizeof(struct kfifo), \
				name##kfifo_buffer + sizeof(struct kfifo))
/*
 * Macros for declaration and initialization of the kfifo datatype
 */

/* helper macro */
#define __kfifo_initializer(s, b) \
	(struct kfifo) { \
		.size	= s, \
		.in	= 0, \
		.out	= 0, \
		.buffer = b \
	}

DEFINE_KFIFO(name, size)  =DECLARE_KFIFO(name, size) +  INIT_KFIFO(name)

/**
 * DEFINE_KFIFO - macro to define and initialize a kfifo
 * @name: name of the declared kfifo datatype
 * @size: size of the fifo buffer. Must be a power of two.
 *
 * Note1: the macro can be used for global and local kfifo data type variables
 * Note2: the macro creates two objects:
 *  A kfifo object with the given name and a buffer for the kfifo
 *  object named name##kfifo_buffer
 */
#define DEFINE_KFIFO(name, size) \
	unsigned char name##kfifo_buffer[size]; \
	struct kfifo name = __kfifo_initializer(size, name##kfifo_buffer)

2. kfifo_in(struct kfifo *fifo, const void *from, unsigned int len) : 入队列操作:

该函数把from指针所指向的 len字节长度的 数据拷贝到fifo所指队列中。

成功则返回推入的字节长度。

/**
 * kfifo_in - puts some data into the FIFO
 * @fifo: the fifo to be used.
 * @from: the data to be added.
 * @len: the length of the data to be added.
 *
 * This function copies at most @len bytes from the @from buffer into
 * the FIFO depending on the free space, and returns the number of
 * bytes copied.
 *
 * Note that with only one concurrent reader and one concurrent
 * writer, you don't need extra locking to use these functions.
 */
unsigned int kfifo_in(struct kfifo *fifo, const void *from,
				unsigned int len)
{
	len = min(kfifo_avail(fifo), len);

	__kfifo_in_data(fifo, from, len, 0);
	__kfifo_add_in(fifo, len);
	return len;
} 
3. kfifo_out(struct kfifo *fifo, void *to, unsigned int len) : 出队列操作:

该函数从 fifo所指向的队列中 拷贝出 长度为len字节的数据 到 to所指的缓冲 中。

成功返回拷贝数据的长度。

/**
 * kfifo_out - gets some data from the FIFO
 * @fifo: the fifo to be used.
 * @to: where the data must be copied.
 * @len: the size of the destination buffer.
 *
 * This function copies at most @len bytes from the FIFO into the
 * @to buffer and returns the number of copied bytes.
 *
 * Note that with only one concurrent reader and one concurrent
 * writer, you don't need extra locking to use these functions.
 */
unsigned int kfifo_out(struct kfifo *fifo, void *to, unsigned int len)
{
	len = min(kfifo_len(fifo), len);

	__kfifo_out_data(fifo, to, len, 0);
	__kfifo_add_out(fifo, len);

	return len;
}
EXPORT_SYMBOL(kfifo_out);
数据被出队列之后,就不再存于队列当中,这是常用队列操作。如果仅仅想“偷窥”下队列中的数据,不想删除它,可以用:

kfifo_out_peek(struct kfifo *fifo, void *to, unsigned int len, unsigned offset)

/**
 * kfifo_out_peek - copy some data from the FIFO, but do not remove it
 * @fifo: the fifo to be used.
 * @to: where the data must be copied.
 * @len: the size of the destination buffer.
 * @offset: offset into the fifo
 *
 * This function copies at most @len bytes at @offset from the FIFO
 * into the @to buffer and returns the number of copied bytes.
 * The data is not removed from the FIFO.
 */
unsigned int kfifo_out_peek(struct kfifo *fifo, void *to, unsigned int len,
			    unsigned offset)
{
	len = min(kfifo_len(fifo), len + offset);

	__kfifo_out_data(fifo, to, len, offset);
	return len;
}
EXPORT_SYMBOL(kfifo_out_peek);
4. 获取队列长度:

a. kfifo_size(struct kfifo *fifo) : kfifo 队列总体长度

/**
 * kfifo_size - returns the size of the fifo in bytes
 * @fifo: the fifo to be used.
 */
static inline __must_check unsigned int kfifo_size(struct kfifo *fifo)
{
	return fifo->size;
}
b. kfifo_len(struct kfifo *fifo) :kfifo队列中已推入数据大小

/**
 * kfifo_len - returns the number of used bytes in the FIFO
 * @fifo: the fifo to be used.
 */
static inline unsigned int kfifo_len(struct kfifo *fifo)
{
	register unsigned int	out;

	out = fifo->out;
	smp_rmb();
	return fifo->in - out;
}
c. kfifo_avail(struct kfifo *fifo) : kfifo队列中,还有多少可用空间

/**
 * kfifo_avail - returns the number of bytes available in the FIFO
 * @fifo: the fifo to be used.
 */
static inline __must_check unsigned int kfifo_avail(struct kfifo *fifo)
{
	return kfifo_size(fifo) - kfifo_len(fifo);
}
d. kfifo_is_empty(struct kfifo *fifo) :是否为空

/**
 * kfifo_is_empty - returns true if the fifo is empty
 * @fifo: the fifo to be used.
 */
static inline __must_check int kfifo_is_empty(struct kfifo *fifo)
{
	return fifo->in == fifo->out;
}
e. kfifo_is_full(struct kfifo *fifo) : 是否已满

/**
 * kfifo_is_full - returns true if the fifo is full
 * @fifo: the fifo to be used.
 */
static inline __must_check int kfifo_is_full(struct kfifo *fifo)
{
	return kfifo_len(fifo) == kfifo_size(fifo);
}
5. kfifo_reset(struct kfifo *fifo) : 重置队列,即清空队列中的内容

/**
 * kfifo_reset - removes the entire FIFO contents
 * @fifo: the fifo to be emptied.
 */
static inline void kfifo_reset(struct kfifo *fifo)
{
	fifo->in = fifo->out = 0;
}
kfifo_free(struct kfifo *fifo) : 撤销队列, 与kfifo_alloc对应。

/**
 * kfifo_free - frees the FIFO internal buffer
 * @fifo: the fifo to be freed.
 */
void kfifo_free(struct kfifo *fifo)
{
	kfree(fifo->buffer);
	_kfifo_init(fifo, NULL, 0);
}
EXPORT_SYMBOL(kfifo_free);
如果是kfifo_init()创建的,还需要释放相关缓冲(buffer)

6. kfifo使用举例:

a. 将0-31压入名为fifo的队列:

unsigned int i;

for(i = 0; i < 32; i++)  //将0 - 31 压入名为fifo的队列中

    kfifo_in(fifo, &i, sizeof(i));
b. 查看一下队列的第一个元素是不是0:
unsigned int val;

int ret;

ret = kfifo_out_peek(fifo, &val, sizeof(val), 0);

if (ret != sizeof(val))

     return -EINVAL;

printk(KERN_INFO, "%u\n",val);

c. 出队列,并打印kfifo中的所有元素,即将上面的0-31 打印出来。

while(kfifo_avail(fifo)) {

    unsigned int val;

    int ret;

    ret = kfifo_out(fifo, &val, sizeof(val));

    if(ret != sizeof(val))

        return -EINVAL;

    printk(KERN_INFO, "%u\n", val);

}


SystemVerilog—队列FIFO与硬件FIFO的区别 SystemVerilog中的队列(Queue)本质上是一种支持​​,其FIFO(先进先出)特性并非由底层存储结构强制实现,而是通过​​和​​来体现。 阅读详情

相关推荐

C++模板FIFO队列实现练习

FIFO队列是一种先进先出的数据结构,它遵循”先到先服务”的原则,广泛应用于任务调度、缓冲处理等场景。FIFO队列确保了数据的处理顺序与到达顺序一致,是操作系统和编程领域中不可或缺的基本概念。模板类是C++中用于实现泛型编程的关键特性之一,它允许程序员编写与数据类型无关的代码。这意味着,同一套代码可以处理不同类型的数据,而无需为每种数据类型重复编写函数或类。在C++中,模板类的定义以关键字template开始,后跟一个或多个模板参数。

weixin_33610780的博客 354

用java来实现FIFO先进先出的队列

简单实现队列先进先出: package com; import java.util.LinkedList; public class MyQueue { private LinkedList list = new LinkedList(); public void put(Object t){ //加入数据 list.addFirst(t); }...

苏凯的博客 7180

FIFO队列的全面设计与实现

任务调度是操作系统的核心功能之一,它负责按照一定的策略组织和管理进程的执行顺序。操作系统采用不同的调度算法来决定进程何时获得CPU时间片以及如何分配这些时间片。调度的目标通常是平衡系统的吞吐量、响应时间、CPU利用率等多个性能指标。内存管理负责监控和控制计算机的主存资源,确保每个进程获得所需内存,同时高效使用有限的物理内存。当系统内存不足时,页面替换算法决定哪个内存中的页面应被移出,以便为新页面腾出空间。FIFO页面替换算法是最早被提出的算法之一,它利用FIFO队列的概念来选择被替换的页面。

weixin_34535286的博客 591

深入了解队列:探索FIFO数据结构及队列

之前介绍了栈: 那就快马加鞭来进行队列内容的梳理。队列和栈有着截然不同的工作方式,队列遵循先进先出(FIFO)的原则,在许多场景下都表现出强大的效率和实用性 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作。此端称为队尾 出队列:进行删除操作。此段称为队头

qq_74415153的博客 3112

Veeam Backup Replication Console 13 备份 PVE

本文介绍了如何通过Veeam Backup & Replication控制台配置与Proxmox VE(PVE)服务器的连接,包括主机地址、用户名密码和SSH信任设置。随后详细说明了部署备份Worker虚拟机的步骤,涵盖网络配置和VM创建。接着指导用户创建PVE虚拟机备份任务,包括命名、选择备份对象、存储位置、备份类型设置,以及配置备份计划任务。最后描述了备份测试执行过程,从启动备份到完成状态通知的完整流程。整个操作涉及服务器连接、Worker部署、备份配置和任务执行四个主要环节。

极致,细节 1602

MCU工程迁移实战:从STM32到MSPM0L1306的完整指南

在嵌入式系统开发中,MCU工程迁移是开发者常面临的核心挑战,涉及从旧平台向新芯片的完整适配。其原理在于不同MCU在硬件架构、外设寄存器映射、时钟树及开发工具链上存在差异,迁移的本质是将应用逻辑与底层硬件实现解耦。这一过程的技术价值在于提升代码复用性、降低硬件切换成本,并确保产品能快速响应供应链或技术栈变化。典型应用场景包括产品升级换代、芯片缺货替代以及技术生态统一。本文以TI MSPM0L1306为例,详解如何通过对比清单分析、DriverLib API替换及分步调试,高效完成从STM32等平台到Arm C

weixin_27625589的博客 330

一步一步学python之(24)队列-FIFO队列

本文介绍了Python中使用queue模块实现FIFO(先进先出)队列的方法。主要内容包括:1)Queue类的基本创建和maxsize参数设置;2)队列操作如put()入队、get()出队;3)队列状态检查方法empty()和full();4)获取队列大小的qsize()方法。文章通过代码示例演示了队列的基本操作,并指出Queue类的线程安全特性使其特别适合多线程环境下的任务调度、缓冲区管理等场景。掌握这些方法可以帮助开发者高效处理并发任务和数据管理问题。

1235

数据科学常见模型总结(二)-倾向性得分匹配模型

PSM的核心思想是从未受干预的用户群体中,找到和干预对象一模一样的用户,这样就可以把因果效应归因到干预上。

wudelong0112的专栏 4889

FIFO队列和优先队列

定义简单的FIFO队列和优先队列 //使用队列必须包含 <queue> 头文件 queue<int>que;//定义que为一个int类型的FIFO队列 queue<char>a;//定义a为一个char类型的FIFO队列 queue<data>c;//定义c为一个date类型的FIFO队列 //data为自定义的数...

lybc2019的博客 909

Autoware1.14-摄像头目标检测YOLO-V3

在Autoware1.14中部署YOLOV3

weixin_43687753的博客 3139

单细胞分析(16)—— RNA Velocity 分析流程

RNA velocity 是一种强大的单细胞转录组分析工具,它可以预测细胞的未来状态,揭示发育轨迹,并用于探索细胞状态转换。RNA velocity 是一种通过单细胞 RNA 测序(scRNA-seq)数据推测细胞未来状态的分析方法。🚀**RNA velocity 提供了一个全新的角度来理解细胞的动态变化,为单细胞转录组分析带来了更深入的时空信息!

阅读文献,记录学习笔记 2979

环形队列(FIFO)

队列是一种常见的数据结构,它是一种线性结构,可以理解为只允许在一端进行插入操作,而在另一端进行删除操作的线性表。在队列中,进行插入操作的一端称为队尾,进行删除操作的一端称为队头。环形队列是一种特殊的队列,它是在队列的基础上添加了一些限制条件,使得队列可以在固定大小的存储空间下进行循环使用。环形队列可以用数组实现,数组中的元素按照一定的顺序排列,并且当队列头或者队列尾指针到达数组的尾部时,会自动从数组的头部开始重新循环使用。

qq_69640653的博客 1351

堆一呼一吸之间:动态扩缩容引发JVM堆内存震荡的伸缩算法、代际传导与容器定容解析

Kubernetes扩容后,新Java实例的GC频率常比老实例高出数倍,堆容量反复伸缩。本文从一次支付系统的GC陡增出发,结合HotSpot源码与JDK 8实测,拆解堆伸缩的记账规则:期望容量以GC后已用量为基数、以Xms为下限,按空闲比例判断扩缩,收缩只在老年代回收后按0%、10%、40%、100%步进;再剖析年轻代随老年代联动、晋升风暴与元空间触发线,对比Parallel、G1、ZGC等收集器及JDK 26的变化,讨论容器分账、HPA共振与原地扩缩容,最后给出分级定容、预热与监控的方案。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 15万+

java实现fifo_java 用什么实现 FIFO队列?

展开全部java使用数据结构来实现32313133353236313431303231363533e58685e5aeb931333337623364FIFO先进先出的队列,实例如下:/**Tochangethistemplate,chooseTools|Templates*andopenthetemplateintheeditor.*/packagelinkedl...

weixin_33124479的博客 823

12027.linux flash驱动之IS25LP01G/IS25WWP01G

一页:512字节 --> 扇区 4096字节 --> 块 32k,64k, 层层递进关系。

写给自己的笔记 2289

R 语言 ggplot2 绘制精美高级全球地图

在本教程中,我们将学习如何使用R语言和ggplot2包绘制精美高级地图。ggplot2是一个功能强大的数据可视化包,它可以让我们创建漂亮、交互式的地图。我们将使用R中的一些其他包来处理地理空间数据,以便与ggplot2无缝协作。

Mrrunsen的博客 1866

java实现fifo算法_java算法:FIFO队列

java算法:FIFO队列FIFO队列是一个ADT,由两个基本操作构成:插入(放入)一个新项,删除(得到)最早插入的项。例1:FIFO队列ADT接口Java代码 interfaceintQueue{intQueue(intq);intempty();voidput(intq);intget();}interface intQueue{intQueue(int q);int empty();void...

weixin_42352351的博客 1685

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

FIFO功能FIFO程序 队列如何实现

在编写串口通信或者CAN通信过程中,为了防止数据丢失及数据卡死等问题,需要设置消息缓存队列,因此需要用C语言编写消息队列函数。2.选项DEV C++开发工具,作为C语言的编译器,用于测试实际的编程效果。

751

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

关于FIFO队列的思考

  有时候我们为了不丢失数据,往往开辟一个FIFO缓冲队列。其中需要用2个数A和B来分别记录当前数据应该放入的位置和当前应该取出数据的位置。   简单的FIFO队列在存储满时,新来的数据直接丢弃。如果想要丢弃最早接收到的数据,则需要做成环形FIFO。   对于环形的FIFO队列,只要存取的速度相当,处理器能保证缓冲队列中始终有空间去存储新来的数据(如果空间足够,且处理时间允许,可以适当开辟一个...

weixin_30556161的博客 178

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Laravel SQS FIFO 队列项目教程

Laravel SQS FIFO 队列项目教程 项目介绍 laravel-sqs-fifo-queue 是一个为 Laravel 框架提供的扩展包,专门用于支持 Amazon SQS FIFO(先进先出)队列。FIFO 队列确保消息严格按照发送顺序进行处理,并且每条消息仅处理一次,非常适合需要严格顺序和去重处理的场景。 项目快速启动 安装 首先,通过 Composer 安装 laravel-sqs...

gitblog_00401的博客 870

FIFO 队列的链表和数组实现

FIFO (First-in, First-out,先进先出)队列:当执行delete操作时事删除那些呆在队列中时间最长的元素。 FIFO 队列是这样一个ADT,包含两个基本操作:插入(put)一个新的项、删除(get)一个最早插入的项。 FIFO 队列的链表实现和数组实现

quinn的专栏 5035

C语言循环数组做FIFO队列

C语言循环数组做FIFO队列 在做通信时,FIFO队列queue是非常好用的,先完成接收通信把接收的数据存在队列里;然后再进行先进先出逐项处理。 C语言用循环数组,通过读位置和写位置循环来实现FIFO队列功能。即数组队列。 1 以1个字节为单位的数组队列的数据结构 使用数组队列,为了方便判断队列空和队列满,使用不完全填满队列,即保留一个元素始终不用 下面是两个例子 char usart1_rev_...

qq_42264326的博客 1118

java算法:FIFO队列

java算法:FIFO队列 FIFO队列是一个ADT,由两个基本操作构成:插入(放入)一个新项,删除(得到)最早插入的项。 例1:FIFO队列ADT接口 Java代码 interface intQueue{       intQueue(int q);       int empty();       void put(int q);       int get(

undoner 2455

Python 内置队列 FIFO vs FILO 队列对比展示

正式的Python专栏第63篇,同学站住,别错过这个从0开始的文章! 之前的多线程解决线程安全的时候,学委展示了两篇关于队列的 带你验收一款线程安全的队列 和使用队列改造转账场景线程安全问题 对比一下FIFO 和 FILO 首先队列这个库里面的queue.Queue类就是一个典型的先进先出队列。 下面写了一些祝福语,使用Queue这个类来编写demo,开头创建一个队列对象q。 后续不断判断队列是否空(q.empty()), 然后通过q.get()调用获取队列元素。 写了三句祝福语,加上序号,先进先出队.

持续学习持续开发,我是雷学委! 2462

队列(FIFO)先进先出

首先引用《啊哈算法》中的一个题,背景就不说了。大体意思就是输入一串数字首先将第一个数字删除,然后将第二个数放在末尾。依次循环,最后按照删除的顺序,把这些数连起来。 这里然后引入队列这个概念,队列是一种特殊的线性结构,只允许在队列的首部进行删除操作-&gt;出队,而在尾部进行插入操作-&gt;入队,当队列为空时,称为空队列。 队列的三个基本元素(一个数组,两个变量) 其次说一下这个题的代码: ...

Let_life_stop的博客 4846
上一篇: copy_from_user() and copy_to_user()
下一篇: 原子操作 atomic_t
lamdoc
博客等级 码龄18年 155粉丝 655原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值