美文网首页
GCD 死锁案例分析

GCD 死锁案例分析

作者: Brucezhang1 | 来源:发表于2017-05-06 21:33 被阅读25次
    案例一:主队列,同步线程
      NSLog(@"dispatch_queue_1");//任务一
    
        dispatch_sync(dispatch_get_main_queue(), ^{
        });
    
        NSLog(@"dispatch_queue_3");// 任务三
    
    // 输出: dispatch_queue_1
    
    • 任务1执行后,同步线程任务2加到主队列中,任务3会等待任务2执行完成后执行
    • 对于队列,有任务来,会将任务加到队尾,然后遵循FIFO原则执行任务,任务2会被添加到队列的队尾,在任务3的后面,会等待任务3执行完毕后执行
    • 综上任务2等待3的执行,同时任务3等到任务2的执行,从而造成了死锁
    案例二:主队列,异步线程
    NSLog(@"dispatch_queue_1");//任务1
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"dispatch_queue_2");// 任务二
        });
        NSLog(@"dispatch_queue_3");// 任务三
    
    // 输出:
    dispatch_queue_1
    dispatch_queue_3
    dispatch_queue_2
    
    • 任务1执行后,异步线程任务2加到主队列中,任务3不会等待任务2执行完成后执行
    • 对于队列,有任务来,会将任务加到队尾,然后遵循FIFO原则执行任务,任务2会被添加到队列的队尾,在任务3的后面,会等待任务3执行完毕后执行
    • 综上任务2等待3的执行,任务3不会等到任务2的执行,从而不会造成死锁,任务执行顺序是 1 3 2.
    案例三:全局队列,同步线程
    NSLog(@"dispatch_queue_1");//任务1
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
              NSLog(@"dispatch_queue_2");//任务2
         });
         NSLog(@"dispatch_queue_3");// 任务3
    
    // 输出:
    dispatch_queue_1
    dispatch_queue_2
    dispatch_queue_3
    
    • 任务1执行后,同步线程任务2加到全局对列(Global Queue)中,任务3会等待任务2执行完成后执行
    • 对于任务2,因为实在全局队列(Global Queue)中,它的执行不受主队列任务的影响,所以任务2在全局队列执行完毕之后会返回到主队列执行任务3
    • 综上任务3等待全局队列中的同步任务2的执行,任务2的执行不会阻塞,从而不会造成死锁,任务执行顺序是 1 2 3.
    案例四:全局队列,异步线程
    NSLog(@"dispatch_queue_1");//任务1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
              NSLog(@"dispatch_queue_2");//任务2
         });
         NSLog(@"dispatch_queue_3");// 任务3
    
    // 输出:
    dispatch_queue_1
    dispatch_queue_2
    dispatch_queue_3
    or 
    dispatch_queue_1
    dispatch_queue_3
    dispatch_queue_2
    
    • 任务1执行后,异步线程任务2加到全局对列(Global Queue)中,任务3不会等待任务2执行完成后执行
    • 对于任务2,因为实在全局队列(Global Queue)中,它的执行不受主队列任务的影响
    • 综上任务3不会等待全局队列中的异步任务2的执行,任务2的执行不会阻塞,从而不会造成死锁,任务执行顺序是 1 2 3 or 1 3 2.
    案例五:串行队列,异步、同步线程
    dispatch_queue_t queue = dispatch_queue_create("com.gcd.serialqueue", DISPATCH_QUEUE_SERIAL);
         NSLog(@"dispatch_queue_1");//任务1    
    _async(queue, ^{
            NSLog(@"dispatch_queue_2");//任务2
            dispatch_sync(queue, ^{
                NSLog(@"dispatch_queue_3");//任务3
            });
            NSLog(@"dispatch_queue_4");//任务4
        });
        NSLog(@"dispatch_queue_5");//任务5
    
    • 任务1执行完成之后,将异步线程任务2,同步队列和任务4加入到串行队列,任务5不需要等待任务2,所以任务2和任务5的执行顺序不一定。
    • 任务2执行完成后,同步线程的任务3加入到串行队列,任务4的执行等待任务3的执行完成
    • 对于队列,有任务来,会将任务加到队尾,然后遵循FIFO原则执行任务,任务3会被添加到队列的队尾,在任务4的后面,会等待任务4执行完毕后执行
    • 综上所述,任务3和任务4陷入无限的等待中,造成死锁
    案例六:异步线程、全局队列,同步线程,主队列
    /*
         1:加入到Main Queue中的有 任务1,异步线程、全局队列,任务5
         2:加入到 Global Queue中的有 任务2,同步线程,主队列,任务4
         */
        NSLog(@"dispatch_queue_1");//任务1
        
        //  执行完任务1后,将异步线程的任务2加到Global Queue中,所以任务5不用等待,结果就是2和5的输出顺序不一定
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSLog(@"dispatch_queue_2");//任务2
            // 执行完任务2,将同步线程的任务添加到主队列中,这时任务3在任务5后面。
            dispatch_sync(dispatch_get_main_queue(), ^{
                NSLog(@"dispatch_queue_3");//任务3
            });
            // 未发生阻塞,执行任务4
            NSLog(@"dispatch_queue_4");//任务4
        });
         NSLog(@"dispatch_queue_5");//任务5
    

    相关文章

      网友评论

          本文标题:GCD 死锁案例分析

          本文链接:https://www.haomeiwen.com/subject/plhytxtx.html