Grand Central Dispatch (GCD) Reference
Grand Central Dispatch (GCD) comprises language features, runtime libraries, and system enhancements that provide systemic, comprehensive improvements to the support for concurrent code execution on multicore hardware in iOS and OS X.
GCD拥有丰富的语言特性,多样的运行库以及能增强系统效率,对于硬件上多核处理器提供了广泛地系统级别的优化,在多核的iOS
OS X硬件体系中,高并发执行能力得到有效地提升.
The BSD subsystem, CoreFoundation,
and Cocoa APIs have all been extended to use these enhancements to help
both the system and your application to run faster, more efficiently, and
with improved responsiveness. Consider how difficult it is for a single
application to use multiple cores effectively, let alone doing it on
different computers with different numbers of computing cores or in an
environment with multiple applications competing for those cores. GCD,
operating at the system level, can better accommodate the needs of all
running applications, matching them to the available system resources in a
balanced fashion.
BSD子系统,CoreFoundation以及Cocoa中的许多APIs都已经大量使用这些新的特性来帮助系统以及你的应用程序提升性能,使其运行得更快,提升交互体验.考虑到要让一款应用能够很有效地利用多核处理器,不管是在不同的电脑上(这个电脑有着不同数量的处理器)或者是同一台电脑上不同应用如何分配多个处理器.GCD,在系统级别上进行运作,能够很好地对所有运行中的程序进行优化,让他们充分利用系统资源的同时,达到一个美妙的平衡.
以上是官方文档前两段的翻译,正如描述中所说,GCD偏向系统调用,更加偏向于底层的函数,效率很高,我将我对于GCD使用的理解加以汇总.
线程是最小的执行单位,而线程需要在指定的线程池中才能够执行,以下是创建线程池的方法.
dispatch_queue_t
dispatch_queue_create(
const char *label
dispatch_queue_attr_t attr);
#pragma mark - 创建并行队列线程池,任务并发执行,一起执行
NS_INLINE
dispatch_queue_t GCD_create_concurrent_queue(NSString
*queueName)
{
// DISPATCH_QUEUE_CONCURRENT
// 线程池提供多个线程来执行任务,所以可以按序启动多个任务并发执行
dispatch_queue_t concurrentQ
= dispatch_queue_create([queueName
cStringUsingEncoding:NSUTF8StringEncoding],
DISPATCH_QUEUE_CONCURRENT);
return concurrentQ;
}
#pragma mark -
创建串行队列线程池,任务依次执行,上一个执行完毕才会执行下一个任务
NS_INLINE dispatch_queue_t
GCD_create_serial_queue(NSString *queueName)
{
//
DISPATCH_QUEUE_SERIAL
//
线程池只提供一个线程用来执行任务,所以后一个任务必须等到前一个任务执行结束才能开始(已经测试,一个任务执行完毕后才回去执行另外一个任务)
dispatch_queue_t
serialQ
= dispatch_queue_create([queueName
cStringUsingEncoding:NSUTF8StringEncoding],
DISPATCH_QUEUE_SERIAL);
return serialQ;
}
#pragma mark - 销毁线程池
NS_INLINE
void GCD_release_queue(dispatch_queue_t queue)
{
#if __has_feature(objc_arc)
#else
dispatch_release(queue);
#endif
}
以下是创建一个单一线程的方法
#pragma mark - 在指定的线程池中执行该线程
NS_INLINE
void GCD_dispatch_async(dispatch_queue_t queue, void
(^block)())
{
//在指定的线程池中执行操作
dispatch_async(queue,
^{
block();
});
}
串行线程池
并发线程池
系统默认就有一个串行队列main_queue和并行队列global_queue,我对其进行了宏定义
//
系统子线程池(并发执行)
#define
SYS_CONCURRENT_QUEUE_H
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
#define SYS_CONCURRENT_QUEUE_D
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0)
#define
SYS_CONCURRENT_QUEUE_L
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)
#define SYS_CONCURRENT_QUEUE_B
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,
0)
// 系统主线程池(序列执行)
#define
SYS_SERIAL_QUEUE
dispatch_get_main_queue()
所以,一般是这么用的,子线程处理数据,结束后把数据传递到主线程,让主线程来更新UI
GCD_dispatch_async(SYS_CONCURRENT_QUEUE_L,
^{
//
long-running task code here
GCD_dispatch_async(SYS_SERIAL_QUEUE,
^{
// update UI code here
});
});
线程的延时操作
#pragma mark - [GCD]
执行某种线程池中的延时操作
NS_INLINE void GCD_DelaySeconds(int64_t seconds,
dispatch_queue_t queue, void (^block)(dispatch_queue_t
queue))
{
dispatch_time_t popTime =
dispatch_time(DISPATCH_TIME_NOW, seconds *
NSEC_PER_SEC);
dispatch_after(popTime, queue,
^(void){
block(queue);
});
}
线程组
#define SYS_CREATE_GROUP dispatch_group_create()
#pragma mark -
线程组,用以监听所有的线程是否已经执行完毕了
NS_INLINE void
GCD_dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue,
void (^block)())
{
dispatch_group_async(group, queue, block);
}
以下是测试依次执行任务(线程)的代码以及结果,从现象以及结果可以看出,只有一个任务完整地执行完毕后才会执行下一个任务,这种线程池一次只处理一个任务
NS_INLINE NSData *
dataFromNetUrlPath(NSString *path)
{
//网络数据URL
return [NSData
dataWithContentsOfURL:[NSURL
URLWithString:path]];
}
以下是测试并发执行任务(线程)的代码以及结果
即使是延时的操作都存在序列执行以及并发执行的区别,看结果
group也存在并发非并发问题,如下所示
Grand Central Dispatch (GCD) (持续更新),布布扣,bubuko.com
Grand Central Dispatch (GCD) (持续更新)
原文:http://www.cnblogs.com/YouXianMing/p/3600763.html