iOS 多线程: 正确认识 GCD 队列类型
2015-11-01 00:09
316 查看
在面试或者跟一些有 ios 编程经验的人聊到关于 GCD 的队列类型的问题.
很多人说自定义的 queue 是串行队列.
这种说法在一定程度上是不对的, 下面具体再说.
今天跟大家聊聊 GCD 中的队列类型问题.
------------------------------------------------------------------------------------------------
目前, GCD 有三种队列类型.
* main queue: 主队列.
* global queue: 全局队列.
* custom queue: 自定义队列.
------------------------------------------------------------------------------------------------
下面具体聊聊吧!
1. main queue
* 获取方式
* 细说
一般使用 main queue, 都是在该线程中操作 UI 相关的.
也就是说, 在 main queue 中执行的任务会在主线程中执行.
主线程只有一个, main queue是与主线程相关的,所以main queue 是串行队列.
2. global queue
* 获取方式
第一个参数是线程的优先级.
第二个参数是保留参数.一般会设置为 0.
可以参考官方注释
* 细说
global queue 是并发队列.可以设置其优先级.
3. Custom queue
* 获取方式
* 细说
这些队列是可以是串行的, 也可以是并行的。默认是串行的.
串行队列可以保证任务是串行的, 保证了执行顺序.类似锁机制.
* 例子
(1). 默认是串行队列.
执行结果
也可以看出, 使用上述方式创建的 queue, 是串行队列. 所以在开头说别人说自定义 queue 是串行的, 并不一定错.
接着看第二个例子.
(2). 指定为串行
执行结果跟例子(1)是一致的.
(3). 指定为并行
执行结果
可以看出, 不是按照顺序执行的.
很多人说自定义的 queue 是串行队列.
这种说法在一定程度上是不对的, 下面具体再说.
今天跟大家聊聊 GCD 中的队列类型问题.
------------------------------------------------------------------------------------------------
目前, GCD 有三种队列类型.
* main queue: 主队列.
* global queue: 全局队列.
* custom queue: 自定义队列.
------------------------------------------------------------------------------------------------
下面具体聊聊吧!
1. main queue
* 获取方式
dispatch_get_main_queue()
* 细说
一般使用 main queue, 都是在该线程中操作 UI 相关的.
也就是说, 在 main queue 中执行的任务会在主线程中执行.
主线程只有一个, main queue是与主线程相关的,所以main queue 是串行队列.
2. global queue
* 获取方式
dispatch_get_global_queue(long identifier, unsigned long flags);
第一个参数是线程的优先级.
第二个参数是保留参数.一般会设置为 0.
可以参考官方注释
/*! * @function dispatch_get_global_queue * * @abstract * Returns a well-known global concurrent queue of a given quality of service * class. * * @discussion * The well-known global concurrent queues may not be modified. Calls to * dispatch_suspend(), dispatch_resume(), dispatch_set_context(), etc., will * have no effect when used with queues returned by this function. * * @param identifier * A quality of service class defined in qos_class_t or a priority defined in * dispatch_queue_priority_t. * * It is recommended to use quality of service class values to identify the * well-known global concurrent queues: * - QOS_CLASS_USER_INTERACTIVE * - QOS_CLASS_USER_INITIATED * - QOS_CLASS_DEFAULT * - QOS_CLASS_UTILITY * - QOS_CLASS_BACKGROUND * * The global concurrent queues may still be identified by their priority, * which map to the following QOS classes: * - DISPATCH_QUEUE_PRIORITY_HIGH: QOS_CLASS_USER_INITIATED * - DISPATCH_QUEUE_PRIORITY_DEFAULT: QOS_CLASS_DEFAULT * - DISPATCH_QUEUE_PRIORITY_LOW: QOS_CLASS_UTILITY * - DISPATCH_QUEUE_PRIORITY_BACKGROUND: QOS_CLASS_BACKGROUND * * @param flags * Reserved for future use. Passing any value other than zero may result in * a NULL return value. * * @result * Returns the requested global queue or NULL if the requested global queue * does not exist. */
* 细说
global queue 是并发队列.可以设置其优先级.
3. Custom queue
* 获取方式
dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
* 细说
这些队列是可以是串行的, 也可以是并行的。默认是串行的.
串行队列可以保证任务是串行的, 保证了执行顺序.类似锁机制.
* 例子
(1). 默认是串行队列.
// 自定义队列(NULL, 默认是串行队列) dispatch_queue_t queue = dispatch_queue_create("gcd.mark", NULL); NSLog(@"create custom queue completed."); dispatch_async(queue, ^{ // 模拟耗时 [NSThread sleepForTimeInterval:2]; NSLog(@"Run First Task"); }); dispatch_async(queue, ^{ NSLog(@"Run Sencond Task"); }); dispatch_async(queue, ^{ NSLog(@"Run Third Task"); });
执行结果
// 执行结果 2015-10-31 23:33:14.267 dsds[87226:1308349] create custom queue completed. 2015-10-31 23:33:16.269 dsds[87226:1308582] Run First Task 2015-10-31 23:33:16.270 dsds[87226:1308582] Run Sencond Task 2015-10-31 23:33:16.270 dsds[87226:1308582] Run Third Task
也可以看出, 使用上述方式创建的 queue, 是串行队列. 所以在开头说别人说自定义 queue 是串行的, 并不一定错.
接着看第二个例子.
(2). 指定为串行
// 指定为串行队列 dispatch_queue_t queue = dispatch_queue_create("gcd.mark", DISPATCH_QUEUE_SERIAL); NSLog(@"create custom queue completed."); dispatch_async(queue, ^{ // 模拟耗时 [NSThread sleepForTimeInterval:2]; NSLog(@"Run First Task"); }); dispatch_async(queue, ^{ NSLog(@"Run Sencond Task"); }); dispatch_async(queue, ^{ NSLog(@"Run Third Task"); });
执行结果跟例子(1)是一致的.
(3). 指定为并行
// 指定为并行队列 dispatch_queue_t queue = dispatch_queue_create("gcd.mark", DISPATCH_QUEUE_CONCURRENT); NSLog(@"create custom queue completed."); dispatch_async(queue, ^{ // 模拟耗时 [NSThread sleepForTimeInterval:2]; NSLog(@"Run First Task"); }); dispatch_async(queue, ^{ NSLog(@"Run Sencond Task"); }); dispatch_async(queue, ^{ NSLog(@"Run Third Task"); });
执行结果
2015-10-31 23:37:06.052 dsds[87270:1310892] create custom queue completed. 2015-10-31 23:37:06.052 dsds[87270:1310988] Run Sencond Task 2015-10-31 23:37:06.052 dsds[87270:1311060] Run Third Task 2015-10-31 23:37:08.057 dsds[87270:1311055] Run First Task
可以看出, 不是按照顺序执行的.
相关文章推荐
- ios中实现staggeringBeauty的效果(二)
- iOS设计模式 - 享元
- ios 多线程
- iOS开发小技巧(二)
- iOS开发小技巧(一)
- iOS9使用提示框进行文本输入的正确实现方式
- Quartz 2D学习(二)绘制曲线
- iOS开发:加广告
- iOS中copy 学习笔记
- 蓝懿ios 技术内容交流和心得分享10.31
- ios中的夜间模式(通知中心)
- YTKNetwork 使用高级教程
- ios开发Swif语言基本的参数、函数、方法的定义和调用
- iOS优化25条建议
- IOS优化
- iOS系统开发:发“彩信”
- #在蓝懿学习iOS的日子#第三个练习日
- iOS系统开发:打电话、发短信
- IOS开发涉及有点概念&相关知识点
- RSA加密算法在iOS9下的问题解决方案