关于GCD(详细)

noj算法设计题——踩气球 踩气球 时限:1000ms 内存限制:10000K 总时限:3000ms 描述: 六一儿童节,小朋友们做踩气球游戏,气球的编号是1~100,两位小朋友各踩了一些气球,要求他们报出自己所踩气球的编号的乘积。现在需要你编一个程序来判断他们的胜负,判断的规则是这样的:如果两人都说了真话,数字大的人赢;如果两人都说了假话,数字大的人赢;如果报小数字的人说的是真话而报大数字的人说谎,则报小数字的人 阅读详情
使用GCD需要注意的地方:
1)更新UI只能在主线程中执行。
2)使用线程不安全的对象要注意
3)创建的dispatch_queue_t要release掉,否则内存会报错。
//==============================================
GCD之dispatch queues:
1、一个dispatch queue是一个像类型的结构,管理着你提交给它的tasks。所有的dispatch queue都是FIFO(先进先出)的数据结构。因此,你添加到queue的task总是以它们添加的顺序启动。GCD自动为你提供了一些dispatch queues,但是你可以创建自己的queue。下面列出了你可以使用的dispatch queue的类型:
1)Searial类型:也称为private dispatch queue,按照添加的顺序在一个时间执行一个task。当前执行的task运行于一个单独的线程(不同的task可能有不同的线程)。Serial queue经常用作同步访问到一个特定的资源。 你可以创建任意多的serial queue,并且每个queue可以和其他queue同时操作。换句话说,如果逆创建了4个serial queue,每个queue在同一时刻只能执行一个task,但是4个queue可以同时执行4个task。
2)Concurrent类型:也称为global dispatch queue,可以同时执行多个task,但是task仍然是按照添加顺序开始执行。同时执行的task在各自的线程中执行。同时执行的task数量在任意时刻都是不同的,这取决于系统条件。你不能自己创建concurrent类型的queue。取而代之的,有3个globla concurrent queue供你使用。使用dispatch_get_global_queue函数获得。有3个不同的优先级.
3)Main dispatch queue:这个queue是全局的serial queue,代表主线程。这个queue工作于应用的run loop。

使用dispatch queue需要注意的:
1)系统决定了同时执行task的总数量。例如逆创建了100个task在100个queue里,它们可能不能同时执行(除非系统又100个有效的cores)。
2)queue的priority影响系统计算启动哪个task。
3)被加入到queue的task必须随时准备好运行。
4)private dispatch queue是reference-counted 对象。符合内存管理规则。

2、QUeue-Related技术
1)Dispatch Groups:用来监视一组block对象的完成。你可以同步或异步地监视。Groups提供了一个有用的同步机制,让代码可以基于其他task的完成。
2)Dispatch semaphores:一个Dispatch semaphores和传统的semaphore类似,但是有更高的效率。
3)Dispatch Sources:一个dispatch source生成notification来响应特定类型的系统事件。你可以使用dispatch sources来监视事件,例如process notification、信号和descriptor events amony others。当一个事件发生时,dispatch source异步提交你的task code到特定的dispatch queue来处理。

3、使用blocks实现tasks:
4、创建和管理Dispatch Queue:
在你添加你的task到queue之前,你需要决定你要使用哪种类型的queue。
1)获得Global Concurrent Dispatch Queues:有3个Global queue,它们只是有不同的优先级。你不需要创建它们。使用dispatch_get_global_queue函数获得。
dispatch_queue_t aQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);//DISPATCH_QUEUE_PRIORITY_HIGH、DISPATCH_QUEUE_PRIORITY_LOW
注意:第2个参数为保留参数,现在只需要使用0即可。
这些global queue object你不需要retain或release(应该因为它们是全局的单例模式,retain和release都不会起作用)。

2)创建Serial Dispatch Queues:
dispatch_queue_t queue;
queue=dispatch_queue_create("com.example.MyQueue",NULL);
//第一个参数为queue name,第二个参数为queue attributes,是为将来保留使用的,现在使用NULL就可以了。

3)获得常用的Queue:
a)使用dispatch_get_current_queue函数来获得当前queue,一般用来作为debug使用。在一个block内部调用这个函数返回block被提交到的queue。在block外部调用这个函数返回默认的concurrent queue。
b)使用dispatch_get_main_queue函数返回主线程queue。
c)使用dispatch_get_global_queue函数来获得任意共享的concurrent queue。

4)Dispatch Queue的内存管理:
使用dispatch_retain和dispatch_release来管理。
即使你使用了垃圾收集系统,你也仍然需要retain和release你的dispatch queue和其他dispatch对象。GCD不支持垃圾收集模型。

5)存储当前context information with a Queue:
所有的dispatch对象(包括dispatch queues)允许你有一个相关的自定义的context数据。使用dispatch_set_context和dispatch_get_context函数来设置和读取。系统不使用你的context data,你需要自己allocate和deallocate它们。
对于queues,你可以使用context data来存储一个指针到一个Objective-C对象或其他数据结构来帮助逆识别queue或其他目的。你可以使用queue的销毁函数来deallocate你的context data。

6)提供queue的清理函数:
使用dispatch_set_finalizier_f函数来设置。相当于dealloc函数。例子:
void myFinalizerFunction(void *context){
  MyDataContext *theData=(MyDataContext *)context;
  //Clean up
  myCleanUpdataContextFunction(theData);
  //release structure itself
  free(theData);
}

dispatch_queue_t createMyQueue(){
  MyDataContext *data=(MyDataContext *)malloc(sizeof(MyDataContext));
  myInitializeDataContextFunction(data);

  //create the queue and set the context data:
  dispatch_queue_t serialQueue=dispatch_create_queue("com.example.CriticalTaskQueue",NULL);
  if(serialQueue){
    dispatch_set_context(serialQueue,data);
    dispatch_set_finalizer_f(serialQueue,&myFinalizerFunction);
  }
  return serialQueue;
}

7)添加tasks到queue:
a)添加一个单独的task到queue:
有两种方法添加:同步或异步。
异步使用dispatch_async和dispatch_async_f函数,一般都优先使用异步。
当你添加一个block对象到queue中后,你无法得知何时代码会执行。所以异步的添加block可以让你在添加的线程中继续做其他的工作。尤其是在主线程中操作时。
使用dispatch_sync和dispatch_sync_f函数来同步添加task。这会阻塞线程直到block执行完。

b)在一个task完成后执行一个completion block:
c)同时迭代循环:
例如,假设逆又一个for 循环如下:
for (i=0;i<count;i++){
  printf("%u\n",i)
}
如果每个迭代的工作都独立于其他迭代,而且迭代完成的顺序也不重要,你可以替换loop为 dispatch_apply或dispatch_apply_f函数。这个函数为每个单独的迭代循环 提交特定的block或函数到一个queue中,当dispatch到一个concurrent global queue中后,就有可能同时执行循环迭代。
注意:像一个常规的for loop,dispatch_apply和dispatch_apply_f函数会在所有的循环迭代完成后才返回。因此你应该小心。避免造成死锁(deadlock)和阻塞主线程。
例子:
dispatch_apply(count,queue,^(size_t i){
  printf("%u\n",i);
});//queue一般为一个global_queue

d)在主线程执行任务
使用dispatch_get_main_queue获得主线程,然后将其传递给dispatch_sync

8)挂起和回复Queues
你可以通过挂起来临时阻止一个queue执行block对象,使用dispatch_suspend函数和dispatch_resume函数。
调用dispatch_suspend使queue的suspension reference count加1,使用dispatch_resume函数减1.相当于retain和release。当reference count大于0时,queue就保持挂起状态。因此,你必须平衡使用suspend和resume。
重要通知:suspend和resume是异步的,而且只在不同的blocks之间生效。挂起一个queue不能使已经运行的block停止运行。

9)使用Dispatch Semaphores来调节有限资源的使用:
如果你的task要访问一些有限的(finite)资源,你可能就想使用一个dispatch semaphore来调整同时访问资源的task的数量。一个dispatch semaphore就像一个常规的semaphore一样工作。当资源可用时,它使用比获得一个传统的系统semaphore更少的时间来获得一个dispatch semaphore。这是因为GCD不需要call down into kernal for this particular case.
使用dispatch semaphore的要点:
a)当你使用dispatch_semaphore_create函数来创建semaphore时,你可以指定一个正整数值来指示resource可用的number值。
b)在每个task中,调用dispatch_semaphore_wait来等待semaphore
c)当wait调用返回时,获得资源并工作。
d)当完成后,释放掉资源并标志semaphore,使用dispatch_semaphore_signal函数。
例子:
//Create the semaphore,specifying the initial pool size
dispatch_semaphore_t fd_sema=dispatch_semaphore_create(getdtablesize()/2);

//wait for a free file descriptor
dispatch_semaphore_wait(fd_sema,DISPATCH_TIME_FOREVER);
fd=open("/etc/services",0_RDONLY);

//release the file descriptor when done
close(fd);
dispatch_semaphore_signal(fd_sema);

10)Waiting on Groups of Queued Tasks:
Dispatch groups用来在其他task执行完之前来堵塞一个线程。
使用dispatch_group_async函数来代替dispatch_async。
使用dispatch_group_wait函数来等待。
例子:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
 
// Add a task to the group
dispatch_group_async(group, queue, ^{
   // Some asynchronous work
});
 
// Do some other work while the tasks execute.
 
// When you cannot make any more forward progress,
// wait on the group to block the current thread.
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
 
// Release the group when it is no longer needed.
dispatch_release(group);

11)Dispatch Queues and Thread Safety线程安全
a)Dispatch Queues本身是线程安全的。换句话说,你可以在任意线程中提交task到dispatch queue。
b)不要使用dispatch_sync函数提交task到当前的queue中。这会造成死锁。
c)避免把使用带锁的任务提交到dispatch queue中,虽然你的task使用锁是安全的,但是当你获得一个lock时,你正在冒险将整个queue堵塞。类似地,对于concurrent queue,等待一个锁可能阻止其他任务执行。如果逆需要在你的代码中同步锁,那就使用一个serial dispatch queue来代替锁。
d)虽然你可以获得运行task的后台线程的信息,但是最好还是不要这么做。

//========================================================================
Grand Central Dispatch(GCD) Reference:只列出了常用的函数
1、创建和管理Queue
dispatch_get_global_queue
dispatch_get_main_queue
dispatch_queue_create
dispatch_get_current_queue
dispatch_queue_get_label

2、添加task到queue
dispatch_async、dispatch_async_f
dispatch_sync、dispatch_sync_f
dispatch_after
dispatch_apply
dispatch_once

3、使用Dispatch groups
dispatch_group_async
dispatch_group_create
dispatch_group_enter
dispatch_group_leave
dispatch_group_notify
dispatch_group_wait

4、管理Dispatch对象:
dispatch_debug
dispatch_get_context
dispatch_set_context
dispatch_release
dispatch_retain
dispatch_suspend
dispatch_resume
dispatch_set_finalizer_f

5、使用Semaphores:
dispatch_semaphore_create
dispatch_semaphore_signal
dispatch_semaphore_wait

6、类型
1)dispatch_block_t :添加到queue中的block原型
typedef void (^dispatch_block_t) (void);

2)dispatch_group_t:添加到一个queue的一组block
typedef struct dispatch_group_s *dispatch_group_t;

3)dispatch_object_t:一个多态类型,GCD dispatch object函数使用的。
typedef union {
 ....
} dispatch_object_t __attribute__((transparent_union));

4)dispatch_once_t:一个predicate,dispatch_once函数使用的
typedef long dispatch_once_t;

5)dispatch_queue_t:
typedef struct dispatch_queue_s *dispatch_queue_t;

7、常量
dispatch_queue_priority_t

#define DISPATCH_QUEUE_PRIORITY_HIGH        2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT     0
#define DISPATCH_QUEUE_PRIORITY_LOW         (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND  INT16_MIN

GCD详解 什么是GCD? Grand Central Dispatch或者GCD,是一套低层API,提供了一种新的方法来进行并发程序编写。从基本功能上讲,GCD有点像 NSOperationQueue,他们都允许程序将任务切分为多个单一任务然后提交至工作队列来并发地或者串行地执行。GCD比之 NSOpertionQueue更底层更高效,并且它不是Cocoa框架的一部分。 除了代码的平行执行能力, 阅读详情

相关推荐

快速gcd vs 普通gcd

听说快速gcd很快,于是我就突发奇想,看看它到底有多快普通gcd函数:ll gcd(ll a,ll b){ ll m=a%b; while(m){ a=b;b=m; m=a%b; } return b; }快速gcd函数:ll kgcd(ll a,ll b){ ll s=1,c; while(a&&b){

NOI,就是与浙江爷爷的一场赛跑 2028

关于GCD的学习笔记

本文不是百分百原创,是本人学习 http://www.cnblogs.com/ziyi--caolu/p/4846555.html 的过程中学习整理的学习笔记,方便后期复习,调用; GCD有以下优点 1.GCD可以将花费时间极其长的任务放到后台线程,可以改善应用的响应性能 2.GCD 提供一个易于使用的并发模型而不仅仅只是锁和线程,以帮助我们避开并发陷阱 3.GCD 具有在常见模式

cewei711的博客 477

【iOS】—— 深入了解GCD

百度:Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上执行的并发任务。在 Mac OS X 10.6 雪豹中首次推出,也可在 iOS 4 及以上版本使用。苹果官方:Grand Central Dispatch(GCD) 是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统级实现。...

m0_55124878的博客 1891

转 Grand Central Dispatch 基础教程:Part 1/2 -swift

本文转载,原文地址:http://www.cocoachina.com/ios/20150609/12072.html  原文 Grand Central Dispatch Tutorail for Swift: Part 1/2 原文作者:Bjrn Olav Ruud 译者:Ethan Joe 尽管Grand Central Dispatch(以下

孙启超 1740

深度学习Halcon中GPU显存利用率高,但GPU、CPU利用率较低,导致模型训练速度很慢,通过设置硬件参数的解决方法

深度学习Halcon中GPU显存利用率高,但GPU、CPU利用率较低,导致模型训练速度很慢,通过设置硬件参数的解决方法 前言 在训练自己模型的时候,会遇到GPU显存利用率高,但GPU、CPU利用率较低,导致模型训练速度很慢的问题。这个问题一方面是由于硬件没有设置到最佳工作状态,另一方面是代码中参数没有设置好。最近在跑Halcon DL遇到这个问题,而Halcon不像开源的几个框架那样自由,代码封装的比较多。所以遇到这种问题,只能在参数最优的情况下,通过设置硬件参数来提升性能。 当然,在跑DL之前,无论什么框

ZiLiangQin的博客 9914

如何下载era5数据?(两种方式)

供水利大数据云计算课程同学参考使用#

Camiel_sweet的博客 1万+

关于GCD(Grand Center Dispatch)

使用GCD需要注意的地方: 1)更新UI只能在主线程中执行。 2)使用线程不安全的对象要注意 3)创建的dispatch_queue_t要release掉,否则内存会报错。 //============================================== GCD之dispatch queues: 1、一个dispatch queue是一个像类型的结构,管理着

yangye的专栏 474

【GD32F407】i2c主机发送,从机中断接收

前言 现在手里负责的一个项目需要用i2c和主芯片进行通信主动发送,中断接收,这就需要支持i2c主机模式和从机模式,先查看原理图 这里我们用到了两条i2c总线进行数据的交替传输,避免在使用一条总线是发送数据和接收数据冲突 初始化i2c控制器 s32_k i2cDevInit(u8 byBusId, TI2cBus *pTI2cBus) { //PCLK = 36000000 BOOL retFlg = FALSE; int I2xSCL = pTI2cBus->byFastMode ?

Enosji的博客 6246

GCD(Grand Center Dispatch)使用详解

一、GCD简介 GCD是苹果公司推出的基于多核CPU多线程技术,GCD属于系统级的线程管理,在Dispatch queue中执行需要执行的任务性能非常高。GCD这块已经开源,地址是 http://libdispatch.macosforge.org。二、按获取方式分类队列 dispatch queue队列就是执行任务的队列,由于遵循 First in First out(先进先出)

MN1107 2592

PINN内嵌物理知识神经网络入门及文献总结

内嵌物理知识深度学习方法(PINN)已经成功用于解决各类科学计算问题,其本质是将物理先验知识嵌入神经网络训练中,将一个求解PDE的问题转化为一个优化问题。这篇博客主要记录PINN相关论文

山里娃的博客 7万+

基于 国产USRP B210 的通信+侦测+干扰三合一实验平台,解锁无线攻防全场景!

在当代复杂电磁环境与多样化通信需求并存的背景下,软件定义无线电(SDR)技术正展现出前所未有的系统灵活性与功能可重构性。由两台USRP-LW B210软件无线电设备模拟无线链路通信过程,能够模拟多种无线通信信号传输及图像传输场景,适用于通信协议验证、抗干扰测试及教学实验。,支持"通信-侦测-干扰-优化"的闭环实验流程,为无线通信领域的教学科研与工程应用提供了一套经济高效、功能完备的解决方案。系统可对通信链路信号进行快速、自动化侦测、识别、告警,并支持多种干扰信号生成、模式切换及效果评估功能。

luowave2012的博客 832

GCD深入学习之GCD的初识

如果移动端访问不佳,可以访问我的个人博客 现在网上关于GCD的介绍已经很多了,在项目中也经常用到,但是没怎么深入研究过,打算写一系列关于GCD使用,参考其他大神写的博客和Apple的技术文档总结一下,一是自己深入学习一下,二是以后忘了可以回过头来温习一下~ 什么是GCD?GCD全名是Grand Central Dispatch(大中央调度器),是系统级的,存在于libdispatch.dylib

W_C__L的博客 7301

小卫星多普勒频偏MATLAB代码

多普勒频偏是由于发射机和接收机之间的相对运动而引起的频率变化。对于小卫星,由于其速度和高度的变化,多普勒频偏会变得更加明显。本文将探讨小卫星多普勒频偏的原理、影响因素以及补偿方法。多普勒频偏的原理当发射机和接收机之间存在相对运动时,接收到的信号频率会发生变化。这种频率变化称为多普勒频偏。其原理可以描述如下:设发射机和接收机之间的距离为 d,发射信号的频率为 f0,发射机和接收机的相对速度为 v。则接收到的信号频率 f 为:其中 c 为光速。

qq_59747472的博客 244

GCD实践——GCD延时执行

这里我将为大家用两种方式来实现延时操作,分别是NSThread和GCD方式。并比较他们的优劣。我把代码放到了Github上面     ,中的GCD02. 【使用NSThread实现延迟】 (1)拖入GCD源码。代码如下: #import "ViewController.h" #import "GCD.h" @interface ViewController () @end @im

乞力马扎罗的雪CYF的博客 3406

数字图像处理:直方图匹配或规定化Histogram Matching (Specification)原理及感悟

本文介绍了连续图像和数字图像直方图匹配(直方图规定化)的原理、处理过程,并提供了案例进行了讲解。可以看到,直方图均衡处理是直方图匹配的一个重要桥梁。 最后,对于直方图规定化这个翻译个人觉得很low,个人感觉叫指定直方图更好理解,但Histogram Specification怎么翻译确实不太好把握,因此还是叫Histogram Matching直方图匹配最好。

老猿Python 2880

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

GCD定时器(GCD Timer)

时间来不及了,赶快上车… /// 创建一个Timer // /** // dispatch_source创建方法 // // @param type 创建的dispatch_source的类型 // @param handle // @param mask // @param queue 添加到的队列 // @return 返回一个新创...

MeteoriteMan的博客 2533

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

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

GCD简介

1. 什么是GCD GCD,全称是Grand Central Dispatch,它是C语言的API. GCD的核心 : 将block(任务)添加到queue(队列)中. 官方文档的描述: Grand Central Dispatch(GCD)是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统级中实现.开发者只需定义想执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并执行任务,这样就比以前的线程更有效率. 2.日常使用 dispatch_queu

吃橘子 1万+

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

iOS——GCD再学习

在异步方法内又同步执行了一个方法,又因为同步执行中的方法执行完成前会阻塞当前线程,因此任务3执行完成前会一直阻塞线程,但是这个同步方法是处于串行队列的,因此要执行任务3要等待任务4执行完,但是任务4又要等任务3执行完才能执行,因此发生了死锁,跟那个主队列+同步执行差不多。syncConcurrent任务在其他线程中执行到追加 任务 1 到主队列中,因为主队列现在没有正在执行的任务,所以,会直接执行主队列的 任务1,等 任务1 执行完毕,再接着执行 任务 2、任务 3。(异步执行 具备开启新线程的能力。

m0_73348697的博客 2243

iOS——【GCD】

GCD指的是Grand Central Dispatch,它是苹果公司开发的一套多线程编程技术。GCD提供了一种简单而有效的方式来管理应用程序中的并发任务。它通过将任务提交到适当的队列(串行队列或并发队列)来管理并发执行的任务,从而帮助开发者更轻松地实现并发编程,提高应用程序的性能和响应速度。上面的就是在后合线程中执行长时间处理,处理结束时,主线程使用该处理结果的源代码。这样,dispatch_async (queue, ^{ 这仅有 一行的代码表示让处理在后台线程中执行。

m0_73348697的博客 1921

【iOS】GCD学习

本博客撰写一下小蓝书的GCDGrand Central Dispatch(GCD)是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统级中实现。开发者只需要定义想执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并计划执行任务。由于线程管理是作为系统的一部分来实现的,因此可统一管理,也可执行任务,这样就比以前的线程更有效率。//让处理在后台线程中执行/**长时间处理*例如AR用画像识别*例如数据库访问*//*

weixin_72437555的博客 1314

GCD

ACM模版GCD最大公约数int gcd(int x, int y) { if (!x || !y) { return x > y ? x : y; } for (int t; t = x % y, t; x = y, y = t); return y; }快速GCDint kgcd(int a, int b) { if (a == 0

逐梦者 3790

c语言gcd 简易函数,简单[GCD]用法详细总结(上)

原文链接:https://www.jianshu.com/p/2d57c72016c6本文用来介绍 iOS 多线程中 GCD 的相关知识以及使用方法。通过本文,您将了解到:1. GCD 简介2. GCD 任务和队列3. GCD 的使用步骤4. GCD 的基本使用(6种不同组合区别)1. GCD 简介什么是 GCD 呢?我们先来看看百度百科的解释简单了解下概念Grand Central Dispa...

weixin_28365523的博客 2905

Maximum GCD(gcd)

题目链接 Given the N integers, you have to find the maximum GCD (greatest common divisor) of every possible pair of these integers. Input The first line of input is an integer N (1 < N < 100) that determines the number of test cases. The following N line

kitalekita的博客 384

GCD基本使用总结

1.GCD的基本使用 1.1 同步执行 + 串行队列 总结:所有任务都是在主线程完成的,证明了同步执行不具备开启新的线程。所有任务都是按序执行。 1.2 同步执行+并发队列 总结:所有任务都是在主线程中执行的,没有开启新的线程,也就是说同步不具备开启新线程的能力。虽然并发队列可以同时执行多个任务,但是当前只有一个线程,一个线程只能执行一个任务,所以这里也就不存在并发队列。 ...

ivolcano的博客 2251
上一篇: 生成静态库方法-iOS集成静态库-iOS合并静态库
下一篇: 使用GCD时的内存管理问题
Allen_iOS
博客等级 码龄12年 3粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值