Dispatch Queues
- Serial Dispatch Queue
单线程模式,一个任务处理完才会执行下一个任务 - Concurrent Dispatch Queue
多线程处理,不等待前一个线程结束就会开始执行下一个线程
Obtaining Dispatch Queues
有两种方式可以创建Dispatch Queues:dispatch_queue_create
和 main dispatch queue / global dispatch queue
dispatch_queue_create
dispatch_queue_t serialQueue = dispatch_queue_create("mySerialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t concurrentQueue = dispatch_queue_create("myConcurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(serialQueue, ^{
NSLog(@"Hello 1");
});
dispatch_async(serialQueue, ^{
NSLog(@"Hello 2");
});
dispatch_async(serialQueue, ^{
NSLog(@"Hello 3");
});
dispatch_async(concurrentQueue, ^{
NSLog(@"Hello 4");
});
dispatch_async(concurrentQueue, ^{
NSLog(@"Hello 5");
});
Main Dispatch Queue/Global Dispatch Queue
这两个方法是用来获得系统提供的Dispatch Queue。main dispatch queue是系统的主线程,主线程是Serial dispatch queue。而Global Dispatch Queue是Concurrent dispatch queue。Global Dispatch Queue有优先级的设置
dispatch_queue_t globalHighQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t globalDefaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t globalLowQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_queue_t globalBackGroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(globalHighQueue, ^{
NSLog(@"high");
});
dispatch_async(globalDefaultQueue, ^{
NSLog(@"default");
});
dispatch_async(globalLowQueue, ^{
NSLog(@"low");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"main");
});
});
dispatch_async(globalBackGroundQueue, ^{
NSLog(@"back");
});
Controlling Dispatch Queues(GCD API使用)
dispatch_set_target_queue
该方法用来变更一个创建好的dispatch queue的优先级,当一个dispatch queue由dispatch_queue_create()创建时,他们默认为default priority。如果要更改就可以使用该方法
dispatch_queue_t globalQueue = dispatch_queue_create("test target", NULL);
dispatch_set_target_queue(globalQueue, globalHighQueue);
dispatch_after
该方法用来在queue里面设定开始任务的时间
dispatch_async(globalHighQueue, ^{
NSLog(@"high");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"high main");
});
});
Dispatch Group
全部任务结束的时候,可能需要做一些处理,利用group可以实现这个功能。
dispatch_group_t group = dispatch_group_create();//创建
dispatch_group_async(group, globalHighQueue, ^{ //添加
NSLog(@"high 1");
});
dispatch_group_async(group, globalHighQueue, ^{
NSLog(@"high 2");
});
dispatch_group_async(group, globalHighQueue, ^{
NSLog(@"high 3");
});
dispatch_group_notify(group,dispatch_get_main_queue(), ^{
NSLog(@"high end");
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);//等待group运行结束
dispatch_barrier_async
用来设置该任务完成之前完全占有线程,比如用来处理读写冲突,当写的时候,读线程必须等待。(对于DISPATCH_QUEUE_CONCURRENT来说)
dispatch_async(concurrentQueue, ^{
NSLog(@"read 1");
});
dispatch_async(concurrentQueue, ^{
NSLog(@"read 2");
});
dispatch_barrier_async(concurrentQueue, ^{
NSLog(@"writing");
});
dispatch_async(concurrentQueue, ^{
NSLog(@"read 3");
});
dispatch_once
只执行一次的API。
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"once");
});
dispatch_suspend/dispatch_resume
挂起和恢复
dispatch_suspend(queue);
dispatch_resume(queue);
dispatch_sync
dispatch_async是异步添加block不会阻塞线程,而dispatch_sync是同步的会阻塞线程的运行,如果当前线程和要处理的block线程相同,就会产生死锁。两者从功能上是差不多的。
dispatch_async(concurrentQueue, ^{
NSLog(@"read 1");
dispatch_sync(concurrentQueue, ^{
NSLog(@"线程阻塞--死锁");
});
});
dispatch_apply
dispatch_apply与dispatch_sync函数和Dispatch Group相关联,该函数按照指定的次数将block追加到Dispatch Group中,并等待执行结束后返回。
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");
参考书籍
《Pro Multithreading and Memory Management for iOS and OS X》