关于GCD队列死锁的分析

2019-03-18  本文已影响0人  流年划过颜夕

在主线程中执行主队列同步任务,会发生什么?
以下代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setSyncDueue];
  
}

- (void)setSyncDueue
{
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue, ^{
        NSLog(@"打印同步执行");
    });
}

答案是死锁

深入研究其原因:
关于dispatch_get_main_queue();官方解释:

/*!
 * @function dispatch_get_main_queue
 *
 * @abstract
 * Returns the default queue that is bound to the main thread.
 *
 * @discussion
 * In order to invoke blocks submitted to the main queue, the application must
 * call dispatch_main(), NSApplicationMain(), or use a CFRunLoop on the main
 * thread.
 *
 * The main queue is meant to be used in application context to interact with
 * the main thread and the main runloop.
 *
 * Because the main queue doesn't behave entirely like a regular serial queue,
 * it may have unwanted side-effects when used in processes that are not UI apps
 * (daemons). For such processes, the main queue should be avoided.
 *
 * @see dispatch_queue_main_t
 *
 * @result
 * Returns the main queue. This queue is created automatically on behalf of
 * the main thread before main() is called.
 */

这个队列默认是绑定与主线程的。
主线程的执行方式就是同步串行。

死锁原因:
1.以默认主线程进行分析:

它执行完viewDidLoad 方法的依据是
(1)先执行完 [super viewDidLoad];
(2)再执行完 [self setSyncDueue];
这个代码块的任务才算执行完成。

但是当调用[self setSyncDueue]
也就是调用- (void)setSyncDueue 时,
需要等里面的

 NSLog(@"打印同步执行");

执行完成才算这个任务完成:

2.加入的同步主队列的任务进行分析:
下面的任务都会放在主线程中同步执行:

dispatch_sync(queue, ^{
        NSLog(@"打印同步执行");
    });。

根据队列先进先出原则,要执行NSLog(@"打印同步执行");的前提是程序执行完viewDidLoad 方法才行。

所以1.等着2.执行NSLog(@"打印同步执行");,2又等着viewDidLoad 方法执行完,
这就出现了死锁问题。

上一篇 下一篇

猜你喜欢

热点阅读