流畅的python笔记(十七)使用期物处理并发

Python学习笔记38:进阶篇(二十七)pygame的使用之时间与帧数控制 Python进阶知识:pygame的使用之时间与帧数控制 阅读详情

目录

前言

一、网络下载的三种风格

依序下载的脚本

使用concurrent.futures模块的下载脚本flags_threadpool.py

期物在哪里

二、阻塞型IO和GIL

三、使用concurrent.futures模块启动进程

四、实验Executor.map方法

五、显示下载进度并处理错误


前言

本章讨论concurrent.futures模块。

期物的概念:期物指一种对象,表示异步执行的操作,是concurrent.futures模块和asynicio包的基础。

一、网络下载的三种风格

为了高效处理网络IO,需要使用并发,因为网络有很高的延迟,所以为了不浪费CPU周期去等待,最好在收到网络响应之前做些其他的事。以下有三个脚本从网上下载20个国家的国旗图像:

  1. flags.py,下载完一个图像,将其保存在硬盘中之后,才请求下一个图像。
  2. flags_threadpool.py,几乎同时请求所有图像,每下载完一个文件就保存一个文件。
  3. flags_asyncio.py,几乎同时请求所有图像,每下载完一个文件就保存一个文件。

依序下载的脚本

 

  1.  导入requests库,这个库不在标准库中,因此按照惯例,在导入标准库中的模块(os、time和sys)之后导入,而且使用一个空行分隔开。
  2.  列出人口最多的20个国家的ISO 3166国家代码,按人口数量逆序排列。得到一个字符串列表。
  3.  获取国旗图像的网站。
  4. 保存图像的本地目录。
  5.  把img保存到DEST_DIR目录中,命名为filename。
  6.  指定国家代码,构建URL,然后下载图像,返回响应中的二进制内容。 
  7.  显示一个字符串,然后刷新sys.stdout,这样能在一行消息中看到进度,在python中得这么做,因为正常情况下遇到换行才会刷新stdout缓冲。
  8. download_many是与并发实现比较的关键函数。
  9. 按字母表顺序迭代国家代码列表,明确表明输出的顺序与输入一致,返回下载的国旗数量。
  10. main函数记录并报告运行download_many函数之后的耗时。
  11. main函数必须调用执行下载的函数;我们把download_many函数当作参数传给main函数,这样main函数可以用作库函数,在后边的示例中接收download_many函数的其他实现。

使用concurrent.futures模块的下载脚本flags_threadpool.py

concurrent.futures模块的主要特色是ThreadPoolExecutor和ProcessPoolExecutor类,这两个类实现的接口能分别在不同的线程或进程中执行可调用的对象。这两个类在内部维护着一个工作线程或进程池,以及要执行的任务队列。此接口抽象层级很高,无需关注实现细节。

  1.  重用flags模块中的几个函数。
  2.  设定ThreadPoolExecutor类最多使用几个线程。
  3.  下载一个图像的函数download_one,这是各个线程中执行的函数。
  4.  设定工作线程数量:等于允许使用的最大值MAX_WORKERS与要处理的数量(即要下载的国旗数量)之间较小的那个值,以免创建多余的线程。
  5. 使用工作的线程数实例化ThreadPoolExecutor类得到executor,executor.__exit__方法会调用executor.shutdown(wait=True)方法,它会在所有线程都执行完毕前阻塞线程。
  6. map方法与内置的map函数类似,其第一个参数是一个函数,第二个参数是一个可迭代对象,把第二个参数中的每个值传给第一个参数产生一个输出。但是这里的executor.map是多线程的,即download_one函数会在多个线程中并发调用。map方法返回一个生成器,因此可以迭代,获取各个函数的返回值。
  7. 调用flags模块中的main函数,传入download_many函数的增强版。

期物在哪里

从python3.4起,标准库中有两个名为Future的类:concurrent.futures.Future和asyncio.Future。这两个类作用相同,都表示可能已经完成或者尚未完成的延迟计算。

        期物封装待完成的操作,可以放入队列,完成的状态可以查询,得到结果(或抛出异常)后可以获取结果(或异常)。

        通常情况下不应自己创建期物,而只能由并发框架(concurrent.futures或asyncio)实例化。因为期物表示终将发生的事情,而确定某件事会发生的唯一方式是执行的时间已经排定。因此只有排定把某件事交给concurrent.futures.Executor子类处理时,才会创建concurrent.futures.Future实例。例如,Executor.submit()方法的参数是一个可调用的对象,调用这个方法会为传入的可调用对象排期,并返回一个期物。

        客户端代码不应改变期物的状态,并发框架在期物表示的延迟计算结束后会改变期物的状态,而我们无法控制计算何时结束。

        concurrent.futures.Future和asyncio.Future这两种期物都有.done()方法,这个方法不阻塞,返回值是布尔值,指明期物链接的可调用对象是否已经执行。客户端代码不会询问期物是否运行结束,而是会等待通知。因此,两个Future类都有add_done_callback()方法,这个方法只有一个参数,类型是可调用的对象,期物运行结束后会调用指定的可调用对象(期物是可调用对象延迟调用的时间?一旦期物结束,就会执行可调用对象?所以多线程程序中期物是用来给每个线程排期的?)。

        此外还有个result()方法:

  • 在期物运行结束后调用的话,这个方法在两个Future类中的作用相同:返回可调用对象的结果,或者重新抛出执行可调用对象时抛出的异常。
  • 如果期物没有运行结束,result方法在两个Future类中的行为相差很大。对concurrent.futures.Future实例来说,调用f.result()方法会阻塞调用方所在的线程,直到有结果返回,此时result方法可以接收可选的timeout参数,如果在指定的时间内期物没有运行完毕,会抛出TimeoutError异常。asyncio.Future.result方法不支持设定超时时间,获取期物的结果最好使用yield from结构,不过对于concurrent.futures.Future实例不能这么做。

        从使用角度理解期物,使用concurrent.futures.as_completed函数,其参数是一个期物列表,返回值是一个迭代器,在期物运行结束后产出期物。

        使用futures.as_completed函数,只需修改download_many函数,把教抽象的executor.map调用换成两个for循环:一个用于创建并排定期物,另一个用于获取期物的结果。

  1. 只使用人口最多的五个国家进行演示。
  2. 把使用的线程数设定为3。
  3. 按照字母表顺序迭代国家代码,明确表明输出的顺序与输入一致。
  4. executor.submit方法排定可调用对象的执行时间,然后返回一个期物,表示这个待执行的操作。
  5. 存储各个期物,后面传给as_completed函数。
  6. 显示一个信息,包含国家代码和对应的期物。
  7. as_completed函数在期物运行结束后产出期物。
  8. 获取该期物的结果。
  9. 显示期物及其结果。

这个例子中调用future.result()方法绝不会阻塞,因为future由as_completed函数产出。

  1.  排定的期物按字母表排序,期物的repr方法会显示期物的状态:前三个期物的状态是running,因为有三个工作的线程。
  2.  后两个期物的状态的pendin,等待有线程可用。
  3.  这一行中第一个CN是运行在一个工作线程中的download_one函数输出,随后内容是download_many函数输出。
  4. 这里有两个线程输出国家代码,然后主线程中的download_many函数输出第一个线程的结果。

 

二、阻塞型IO和GIL

CPython解释器本身就不是线程安全的,因此有全局解释器锁GIL,一次只允许使用一个线程执行python字节码。因此一个python进程通常不能同时使用多个CPU核心。

        编写python代码时无法控制GIL,不过执行耗时的任务时,可以使用一个内置的函数或一个使用C语言编写的扩展释放GIL。其实有个使用C语言编写的python库能管理GIL,自行启动操作系统线程,利用全部可用的CPU核心。但这样做会极大增加库代码的复杂度。

        然而,标准库中所有执行阻塞型IO操作的函数,在等待操作系统返回结果时都会释放GIL,这意味着在python语言这个层次上可以使用多线程,而IO密集型python程序会从中受益:一个python线程等待网络响应时,阻塞型IO函数会释放GIL,再运行一个线程。

        

三、使用concurrent.futures模块启动进程

这个模块实现的是真正的并行计算,因为它使用ProcessPoolExecutor类把工作分配给多个python进程处理。因为如果需要CPU密集型处理,使用这个模块能绕开GIL,利用所有可用的CPU核心。

        ProcessPoolExecutor和ThreadPoolExecutor类都实现了通用的Executor接口,因此使用基于concurrent.futures模块能轻松把基于线程的方案转成基于进程的方案。

这两个实现Executor接口的类唯一值得注意的区别是,ThreadPoolExecutor.__init__方法需要max_workers参数,指定线程池中线程的数量。在ProcessPoolExecutor类中,那个参数是可选的,而且大多数情况下不使用,因为默认值是os.cpu_count()函数返回的CPU数量。对于CPU密集型的处理来说,不可能要求使用超过CPU数量的职程。而对IO密集型处理来说,可以在一个ThreadPoolExecutor实例中使用10个、100个或1000个线程,最佳线程取决于做的什么事,以及可用内存有多少,要仔细测试才能找到最佳线程数。

四、实验Executor.map方法

若想并发运行多个可调用的对象,最简单的方式是使用Executor.map方法。

  1. display函数的作用就是把传入参数打印出来,并在前边加上时间戳。
  2. loiter函数在开始时显示一个消息,然后休眠n秒,最后在结束时再显示一个消息,消息用制表符缩进,缩进的量由n的值确定。
  3. loiter返回n*10。
  4. 拆功能键ThreadPoolExecutor实例,有3个线程。
  5. 把5个任务提交给executor,range(5)是可迭代对象,可以传5个值给loiter函数。因为只有3个线程,因此只有3个任务会立即开始:loiter(0)、loiter(1)、loiter(2)。这是非阻塞调用。
  6. 立即显示调用executor.map方法的结果:一个生成器results。
  7. for循环中enumerate函数会隐式调用next(results),这个函数又会在内部表示第一个任务loiter(0)的_f期物上调用_f.result()方法。result方法会阻塞,直到期物运行结束,因此这个循环每次迭代时都要等待下一个结果做好准备。

  1.  这次运行从15:56:50开始。
  2.  第一个线程执行loiter(0),因此休眠0秒,甚至会在第二个线程开始之前就结束。
  3.  loiter(1)和loiter(2)立即开始,因为线程池中有三个职程,可以并发运行三个函数。
  4.  executor.map方法返回的结果results是生成器,不管有多少任务,也不管max_workers的值是多少,目前不会阻塞。
  5. loiter(0)运行结束了,第一个职程可以启动第四个线程,运行loiter(3)。
  6. 此时执行过程可能阻塞,具体情况取决于传给loiter函数的参数:results生成器的__next__方法必须等到第一个期物运行结束。此时不会阻塞,因为loiter(0)在循环开始前结束。注意这一点之前的所有时间都在同一刻发生(15:56:50)。
  7. 一秒钟后,即15:56:51,loiter(1)运行完毕,这个线程闲置,可以开始运行loiter(4)。
  8. 显示loiter(1)的结果:10。现在for循环会阻塞,等待loiter(2)的结果。
  9. 同上:loiter(2)运行结束,显示结果;loiter(3)也一样。
  10. 2秒钟后loiter(4)运行结束,因为loiter(4)在15:56:51开始,休眠了4秒。

 

五、显示下载进度并处理错误

暂略。

 

分享:流畅的Python (图灵程序设计丛书) 链接: https://pan.baidu.com/s/1lVDmCXJR1wnsPki-0sc1kQ 提取码: mhkg 复制这段内容后打开百度网盘手机App,操作更方便哦 阅读详情

相关推荐

基于流畅的Python第二版学习笔记

基于流畅的Python第二版学习笔记

python threadpoolexecutor_python – ThreadPoolExecutor().map与ThreadPoolExecutor()的不同.submit?...

我只是很困惑的一些我写的代码.我很惊讶地发现:with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:results = list(executor.map(f, iterable))和with concurrent.futures.ThreadPoolExecutor(max_workers=4) as exec...

weixin_39879122的博客 1541

Klocwork安装

简单介绍一下Klocwork在windows下的安装,操作系统是win7,Klocwork的版本是10.0。 第一步:由于Klocwork的安装程序已十分成熟,所以在安装之前不需要什么准备共走。双击Klocwork的安装包,会出现下图的安装引导界面,点击Next按钮。 第二步:下图是协议界面,点击Next按钮。 第三步:选择Klocwork的安装目录,点击Next按钮 第四步:

旮旯 9931

python多任务【一】- 线程

python的thread模块是比较底层的模块,python的threading模块是对thread做了一些包装的,可以更加方便的被使用 1. 使用threading模块 单线程执行 # coding=utf-8 import time def say_sorry(): print("嗨,你好!我能帮助你吗?") time.sleep(1) if __name__ == "__main__": for i in range(5): say_sorry(

Rnan_prince的博客 1022

Java:使用Java调用打印机进行打印(JPG、PDF和Word三种文件格式)

目录 一、Java的打印简介 二、Java打印实现 2.1 JPG图片文件格式打印实现 2.2 PDF文件格式打印实现 2.3 Word文件格式打印实现 2.3.1 Word文件采用jacob插件进行打印实现。 2.3.2 先将word转化为pdf文件,然后打印pdf(lz使用) 三、总结 一、Java的打印简介 在我们的实际工作中,经常需要实现打印功能。但由于历史原因,Jav...

vatxiongxiaohui的专栏 8万+

Linux系统下SAPGUI安装包选择与避坑指南

本文详细介绍了在Linux系统下选择和安装SAPGUI安装包的策略与避坑指南。重点解析了不同版本安装包的关键区别,特别是Linux版必须包含linux-lib.jar和linux64-lib.jar文件,避免误用Mac或Windows版导致的兼容性问题。文章还提供了针对Ubuntu、RHEL等不同Linux发行版的安装实战指南,以及常见报错的解决方案,帮助用户顺利完成SAPGUI的安装与配置。

weixin_28366353的博客 675

python线程池结果回收

如果第一个调用生成结果用时10秒, 而其他调用只用 1 秒, 代码会阻塞 10 秒, 获取map方法返回的生成器产出的第一个结果。在此之后,获取后续结果时不会阻塞, 因为后续的调用已经结束。如果不关注线程的启动顺序,只需要收集结果的话,使用submit+as_complete,实现谁先完成就返回谁。同样的,以下用例实现了使用线程池获取a*b的结果,并将结果以队列形式存储在res_lists中。以下用例实现了使用线程池获取a*b的结果,并将结果以队列形式存储在res_lists中。

qq_58785091的博客 839

SBM与超效率SBM模型实战:从原始面板数据到MATLAB高效实现

本文详细介绍了SBM模型与超效率SBM模型的核心原理,并提供了从原始面板数据预处理到MATLAB高效实现的完整实战指南。通过具体代码解析,帮助研究者掌握如何利用MATLAB进行数据标准化、模型构建、效率求解及结果可视化,从而精准评估决策单元的相对效率,尤其适用于在高效单元中进一步精细排名的场景。

weixin_29100399的博客 479

流畅的python第十七章使用期物处理并发

从 Python 3.4 起,标准库中有两个名为 Future 的类:concurrent.futures.Future 和asyncio.Future。这两个类的作用相同:两个 Future 类的实例都表示可能已经完成或者尚未完成的延迟计算 我们要记住一件事:通常情况下自己不应该创建期物,而只能由并发框架(concurrent.futures 或 asyncio)实例化。原因很简单:...

anyangyu0343的博客 179

解密GPT-5-Codex CLI安全最佳实践:从API Key保护到沙箱模式详解

本文深入解析GPT-5-Codex CLI在企业环境中的安全最佳实践,涵盖API Key全生命周期管理、沙箱模式配置及网络传输加固等核心防护策略。通过分层存储方案、动态环境变量加载和精细化权限设计,帮助开发团队构建企业级AI编程助手的安全防线,有效预防密钥泄露和未授权访问风险。

weixin_29309785的博客 585

Vue2 - 最新详细实现网站内部打开预览 office 全套附件,在页面弹窗内解析预览 word文档、excel电子表格、ppt演示文稿(docx|xlsx|pptx|pdf|txt等文件)详细代码

vue2,nuxt2,office,文档,文件,查看预览,弹框预览,下载预览,如何预览pdf文档,打开查看,office全套文档,实现在线预览文件,小程序内预览word文件,手机h5移动端网页,nuxt文档在线预览,预览office最好用的插件,下载查看,Office在线预览,vue-office,vue如何使用vue-office教程示例,word文档,ppt,exce表格,预览电子文件,文档无法解析,打不开,报错,失效,保存下载,vue前端预览并下载doc、xls、pdf、txt及图片,vue2中预览p

🏆 前端领域优质创作者 1万+

流畅的Python(十七)-使用future处理并发

主要以三个模拟网络下载的代码-分别是依序下载、使用中的方法、以及使用该模块的和方法,来展示Python实现的其中一种方式。

weixin_37901366的博客 1527

Android SELinux——neverallow问题处理(十六)

遇到 neverallow 规则问题,千万别急着去注释/剔除里面原有的规则(原生的尽量别动)。增加 allow 规则是常见的解决办法,但是随着 android 版本的升级,系统对 SELinux 的管控越来越严,增加了大量的 neverallow。一般情况下,向默认标签授予权限的做法是错误的,其中许多权限都是 neverallow 规则所不允许的。按照上面方法去添加 SELinux 可能会违反了 neverallow 规则,编译时候会报 neverallow 相关的错误。

小旭的专栏 2673

流畅python学习笔记:第十七章:并发处理

第十七章:并发处理 本章主要讨论Python3引入的concurrent.futures模块。在python2.7中需要用pip install futures来安装。concurrent.futures 是python3新增加的一个库,用于并发处理,提供了多线程和多进程的并发功能类似于其他语言里的线程池(也有一个进程池),他属于上层的封装,对于用户来说,不用在考虑那么多东西了。 ...

dianjie9145的博客 184

《Linux GPU 驱动核心机制:面向图形与 AI 计算的 DRM 内存管理与任务调度》 目录

本文以缓冲区对象(BO)生命周期为主线,系统解析 Linux DRM 子系统中 GPU 驱动的核心机制。涵盖 GEM 与 TTM 内存管理、dma-buf/dma-fence 共享同步、GPU 调度与地址空间管理,结合 amdgpu、Xe 等驱动代码,深入剖析其设计动机与实现逻辑。旨在填补中文领域对 GPU 内核机制系统性讲解的空白,为图形与 AI 计算场景下的内存泄漏、同步死锁等疑难问题提供可追溯的分析路径。

图形/计算GPU的驱动与虚拟化技术分享园地 3727

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

流畅python学习笔记:第十七章:并发处理二

本章讨论python3.2引入的concurrent.futures模块。future是中文名叫期物。期物是一种对象,表示异步执行的操作 在很多任务中,特别是处理网络I/O。需要使用并发,因为网络有很高的延迟。所以为了不浪费CPU周期去等待,最好在收到网络响应之前做些其他的事。 首先来看下并发和非并发的两个脚本,来对比下各自的运行效率。在这个程序中,我们通过脚本去网站下载各个国家的国...

dianjie9145的博客 286

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

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

《流畅的Python》第十七章学习笔记

concurrent.futuresconcurrent.futures模块的主要特色是ThreadPoolExecutor和ProcessPoolExecutor类。这两个类实现的接口能...

测试游记 141

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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

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

流畅的 Python 第二版(GPT 重译)(九)

迭代在语言中是如此深入,以至于我喜欢说 Python 理解迭代器。[¹⁷] 在 Python 语义中集成迭代器模式是设计模式在所有编程语言中并非都适用的一个主要例子。在 Python 中,一个经典的手动实现的迭代器,如示例 17-4,除了作为教学示例外,没有实际用途。在本章中,我们构建了几个版本的一个类,用于迭代可能非常长的文本文件中的单词。我们看到 Python 如何使用iter()内置函数从类似序列的对象创建迭代器。我们构建了一个经典的迭代器作为一个带有__next__()

龙哥盟 1570

python:并发编程(二十六)

本文将和大家一起探讨python并发编程的实际项目:win图形界面应用(篇八,共八篇),系列文章将会从零开始构建项目,并逐渐完善项目,最终将项目打造成适用于高并发场景的应用。

weixin_43431593的博客 573

全民一起学python之基础篇-杨洋全民一起玩Python 之 基础篇【完结】网易云课堂...

总大小:4.3 GB└—python电子书├—fluent-python-2015-.pdf 17.5 MB├—learn-python3-the-hard-way-jul-4-2017.pdf 1.3 MB├—Python Crash Course - A Hands-On, Project-Based Introduction to Programming.pdf 5.4 MB├—Python...

weixin_39927623的博客 1123

Python 技术手册第三版(一)

原文:annas-archive.org/md5/9e375b08cb0be52e8b7c2a9eba6f5313 译者:飞龙 协议:CC BY-NC-SA 4.0 前言 Python 编程语言调和了许多表面上的矛盾:优雅而实用,简单而强大,非常高级却在您需要处理位和字节时不会阻碍您,适合初学者也适合专家。 本书面向有一定 Python 经验的程序员,以及从其他语言首次接触 Python 的经验丰富的程序员。它提供了对 Python 本身、其庞大标准库中最常用部分的快速参考,以及一些最受欢迎和有用的第三

龙哥盟 1501

Python 进阶(十七) UV 实战:从零构建高效 Python 开发环境

本文详细介绍了如何使用极速的Python包管理工具UV从零构建高效的开发环境。通过对比传统工具,阐述了UV在项目初始化、虚拟环境管理、依赖安装与同步等方面的巨大性能优势,并提供了FastAPI项目的实战案例,帮助开发者显著提升工作效率。

rainy的博客 401

RealPython 中文系列教程(一百二十七)

原文:RealPython 协议:CC BY-NC-SA 4.0 用 Python 中的 AI 播放器构建井字游戏引擎 原文:https://realpython.com/tic-tac-toe-ai-python/ 当你还是个孩子的时候,你会学着玩井字游戏,有些人称之为十字游戏。直到你进入青少年时期,这个游戏仍然充满乐趣和挑战。然后,你学习编程,发现为这个双人游戏的虚拟版本编码的乐趣。作为一个成年人,你可能仍然会欣赏用 Python 创造一个拥有人工智能(AI) 的对手的游戏的简单性。 通过完成

龙哥盟 3170

Python | 第十七章 | pyecharts开发图表 | 折线图 | 地图 | 轮播图

参考文档1参考文档2概况Echarts是一个由百度开源的数据可视化技术,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而Python很适合用于数据处理。当数据分析遇上数据可视化时pyecharts诞生了。特性简洁的API设计,使用如丝滑般流畅,支持链式调用囊括了30+种常见图表,应有尽有支持主流Notebook 环境,Jupyter Notebook和JupyterLab可轻松集成至Flask,Django等主流Web 框架。

ZJC744575的博客 1166

转转前端周刊第七十七期

转转前端周刊本刊意在将整理业界精华文章给大家,期望大家一起打开视野如果你有发现一些精华文章想和更多人分享,可以点击我们的公众号名称,将文章链接和你的解读文案发给我们!我们会对内容进行筛选和审核,保留你的推荐人署名,分享给更多的人1、深入浅出 Web3:合约项目区块链 合约就是用计算机语言取代了法律语言记录条款并由程序自动执行的合约。简单来说,就是用来保证交易完成的一种数字化约定。2、CSS 的 w...

大转转FE 302

python人工智能_人工智能(机器学习)学习之路推荐——Python

人工智能(机器学习)学习之路推荐——Python虽然自己学过C,但是自己曾从事python后端开发、python算法工程师岗位、Python(机器学习)讲师,所以本篇文章主要通过python来介绍机器学习的路线。当然,前期的机器学习基础的推荐,是不会分语言的。纯小白——计算机小白如果你是完完全全的纯小白,并且只会计算机这三个字。 1. 个人推荐你可以看看《计算机科学导论》(专业书籍个人推荐看纸质书...

weixin_39891317的博客 395
上一篇: 流畅的python笔记(十六)协程
下一篇: 流畅的python笔记(十九)动态属性和特性
罗古洞的女婿
博客等级 码龄10年 1117粉丝 125原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值