您的位置:首页 > 移动开发 > IOS开发

iOS 多线程: 正确认识 GCD 队列类型

2015-11-01 00:09 316 查看
在面试或者跟一些有 ios 编程经验的人聊到关于 GCD 的队列类型的问题.

很多人说自定义的 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

可以看出, 不是按照顺序执行的.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: