GCD常用函数总结
来源:互联网 发布:大数据产业测度 编辑:程序博客网 时间:2024/05/17 21:53
GCD提供两种Dispatch Queue, 分别为Concurrent Dispatch Queue 和 Serial Dispatch Queue.
Serial Dispatch Queue 使用一个thread。
Concurrent Dispatch Queue 使用多个thread。
获取Dispatch Queue:
0)dispatch_queue_create
dispatch_queue_t queue = dispatch_queue_create("name.of.your.queue",NULL);
第一个参数为queue的名字,第二个参数传NULL表明要创建一个Serial Dispatch Queue, 传入DISPATCH_QUEUE_CONCURRENT 创建一个 Concurrent Dispatch Queue。
如果是对数据库表更新或更新文件,最好为每一个表或文件建立一个Serial Dispatch Queue,这样能保证只有一个thread会对数据进行更新。
如果对那些不会引起数据不一致问题的任务,需要放到Concurrent Dispatch Queue执行。
1)从Main Dispatch Queue/Global Dispatch Queue获取// main queue dispatch_queue_t mainQueue = dispatch_get_main_queue(); // global queue of high prority dispatch_queue_t globalHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); // global queue of default priority dispatch_queue_t globalDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // global queue of low priority dispatch_queue_t globalLow = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0);// global queue of background priority dispatch_queue_t globalBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);
Global Dispatch Queue -> Concurrent dispatch queue
dispatch_set_target_queue:主要用来给新建的queue设置优先级dispatch_queue_t serialQueue = dispatch_queue_create("name.of.queue",NULL);dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);dispatch_set_target_queue(serialQueue, globalQueue);需要注意的是,第一个参数是自定义的queue,而不是系统的queue。因为你不能给系统的queue设置权限。通过上面设置,serialQueue 就有了与globalQueue一样的优先级。其实这个函数不仅可以设置queue的优先级,还可以设置queue之间的层级结构。
dispatch_after: 过一段时间执行queue中的task
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_SEC);dispatch_after(time, dispatch_get_main_queue(),^{ NSLog(@"after 3 seconds...");});
Dispatch Group
0)dispatch_group_notify
dispatch group 可以在group中的dispatch queue都执行完之后,通过一个dispatch_group_notify通知回调。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);dispatch_group_t group = dispatch_group_create();dispatch_group_async(group, queue, ^{NSLog(@"task1");});dispatch_group_async(group, queue, ^{NSLog(@"task2");});dispatch_group_async(group, queue, ^{NSLog(@"task3");});dispatch_group_notify(group, dispatch_get_main_queue(), ^{NSLog(@"finished...");});输出总会保证"finished..."会在最后一句输出。
1)dispatch_group_wait
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);dispatch_group_t group = dispatch_group_create();dispatch_group_async(group, queue, ^{NSLog(@"task1");});dispatch_group_async(group, queue, ^{NSLog(@"task2");});dispatch_group_async(group, queue, ^{NSLog(@"task3");});dispatch_group_wait(group, DISPATCH_TIME_FOREVER);dispatch_group_wait提供了一种类似超时的机制,当然如果等待时间设置为DISPATCH_TIME_FOREVER,功能和dispatch_group_notify是一样的。
dispatch_barrier_async
dispatch_barrier_async是一个可以让当前任务等待queue其他任务完成再执行的函数。例如,从数据库读取数据是可以多线程并发读取的,因为这样提高效率。但是,更新数据库数据,就要保证只有一个线程进行更新操作。所以,当更新操作发生的时候,一定要保证读操作和其他更新操作等待。
dispatch_queue_t queue = dispatch_queue_create("barrier.queue", DISPATCH_QUEUE_CONCURRENT);dispatch_async(queue, read_block_0);dispatch_async(queue, read_block_1);dispatch_async(queue, read_block_2);dispatch_async(queue, read_block_3);dispatch_async(queue, read_block_4);dispatch_barrier_async(queue, update_block);dispatch_async(queue, read_block_5);dispatch_async(queue, read_block_6);dispatch_async(queue, read_block_7);dispatch_async(queue, read_block_8);dispatch_async(queue, read_block_9);这样就可以保证只有当更新操作结束后,才会进行其他数据库读操作,保证了数据的一致性。
dispatch_apply
dispatch_apply用于给一个block添加到dispatch queue若干次。 “for”循环
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);dispatch_apply(10, queue, ^(size_t index) { NSLog(@"%zu",index);});NSLog(@"done...");
dispatch_suspend/dispatch_resume
用于暂停和继续执行queue
dispatch semaphore
dispatch semaphore 适合处理比dispatch queue或者dispatch_barrier_async更小颗粒度的操作。
例如,
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);NSMutableArray *array = [[NSMutableArray alloc] init];for (int i = 0; i < 100000; i++){ dispatch_async(queue, ^{ [array addObject:[NSNumber numberWithInt:i]]; });}
如果执行上段代码,因为NSMutableArray不是thread safe的,所以在global queue中对其进行添加对象,会导致程序crash掉。
使用dispatch semaphore我们可以实现多线程对NSMutableArray进行操作
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);NSMutableArray *array = [[NSMutableArray alloc] init];for (int i = 0; i < 100000; i++){ dispatch_async(queue, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); [array addObject:[NSNumber numberWithInt:i]]; dispatch_semaphore_signal(semaphore); });}dispatch semaphore 是一个信号量的counter,当counter为0,当前线程停止运行,当大于0,自减1,继续执行。
dispatch_semaphore_create
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);初始化一个counter为1的semaphore.
dispatch_semaphore_wait
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);等待counter大于0才运行,第二个参数为等待时间。执行后counter减1.
dispatch_semaphore_signal
dispatch_semaphore_signal(semaphore);给counter加1
所以在上面的代码中,就可以保证在wait和signal中的[array addObject:[NSNumber numberWithInt:i]]; 就只有一个thread进行操作,保证了线程安全。
dispatch_onece
保证了dispatch_once中的代码只会被执行一次,常用于单例。
+ (id)sharedManager { static MyManager *sharedMyManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedMyManager = [[self alloc] init]; }); return sharedMyManager;}
出自 http://my.oschina.net/u/566401/blog/224141
- GCD常用函数总结
- iOS GCD常用函数总结
- GCD常用函数说明
- GCD常用函数
- GCD常用函数
- GCD函数简单总结
- iOS GCD常用方法总结
- GCD的常用方法总结
- 网络多线程-GCD常用函数
- GCD中常用的函数
- iOS GCD集汇(三)GCD常用方法总结
- GCD中常用函数及释义
- GCD常用函数和文件剪切
- 多线程学习11-GCD常用函数
- 常用GCD
- asp常用函数总结
- php常用函数总结
- DB2常用函数总结
- 如何做到每天写代码?
- 【软考】(二)计算机组成原理-cpu
- Synchronization and Overlapped Input and Output
- RAII惯用法:C++资源管理的利器
- 【算法】 递归求解整数划分
- GCD常用函数总结
- 面试经典(21)--最大回文
- JSP使用UrlRewriteFilter实现网站伪静态
- 第八周项目1-实现复数类中运算符的重载
- Linux中带缓冲IO和不带缓冲IO的详细说明
- 使用广播接收器
- VMware和VirtualBox中的网络适配器类型及虚拟网络性能优化
- java.lang.NoSuchMethodError解决办法,
- 深入理解Servlet线程安全问题