iOS GCD 死锁理解

作者: FaiChou | 来源:发表于2016-05-19 19:07 被阅读385次

    关键字:串行并行同步异步阻塞死锁
    作者:周辉
    All rights reserved.

    同步(dispatch_sync):

    dispatch_sync(fcQueue, ^{ 
        NSLog(@"1"); // 任务 1 
    }); 
    NSLog(@"2");  // 任务 2
    dispatch_sync(fcQueue, ^{ 
        NSLog(@"3"); // 任务 3 
    }); 
    NSLog(@"4"); // 任务 4
    

    输出:“1234”

    异步(dispatch_async):

    dispatch_async(serialQueue, ^{ 
        NSLog(@"1"); //任务 1 
    }); 
    NSLog(@"2"); 
    dispatch_async(serialQueue, ^{ 
        NSLog(@"3"); //任务 3 
    }); 
    NSLog(@"4");
    

    上面代码执行结果可能为 “1234”、“1243”、“2134”、“2143”、“2413”中的一种,2 始终在 4 前面,1 始终在 3 前面,2 始终在 3 前面。

    死锁

    NSLog(@"1"); // 任务1
    dispatch_sync(dispatch_get_main_queue(), ^{ 
        NSLog(@"2"); // 任务2
    });
    NSLog(@"3"); // 任务3
    

    输出: 1

    MainQueue.png

    如图所示,代码中dispatch_sync(dispatch_get_main_queue(), ^{ });会获取主线程(当前线程)阻塞之,执行完任务1就不会继续走任务2,它会把任务2放到任务3后面,等到任务2执行完才会打通阻塞的地方继续执行,可是任务2不可能执行完,因为主线程已经堵住了~

    Go on

    NSLog(@"1"); // 任务1
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
        NSLog(@"2"); // 任务2
    });
    NSLog(@"3"); // 任务3
    

    输出: 1 2 3

    同步线程2

    Go on

    dispatch_queue_t queue = dispatch_queue_create("com.fcDemo.serialQueue", DISPATCH_QUEUE_SERIAL);
    NSLog(@"1"); // 任务1
    dispatch_async(queue, ^{
        NSLog(@"2"); // 任务2
        dispatch_sync(queue, ^{
            NSLog(@"3"); // 任务3
        });
        NSLog(@"4"); // 任务4
    });
    NSLog(@"5"); // 任务5
    

    输出:1 5 21 2 5

    Go on

    NSLog(@"1"); // 任务1
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"2"); // 任务2
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"3"); // 任务3
        });
        NSLog(@"4"); // 任务4
    });
    NSLog(@"5"); // 任务5
    

    输出: 1253415234

    Go on

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"1"); // 任务1
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"2"); // 任务2
        });
        NSLog(@"3"); // 任务3
    });
    NSLog(@"4"); // 任务4
    while (1) {
    }
    NSLog(@"5"); // 任务5
    

    输出:1441


    -“大圣,此去欲何?”
    -“踏南天,碎凌霄。”
    -“如若一去不回...”
    -“便一去不回。”

    有此等的英勇壮志奈何一个GCD乎?

    相关文章

      网友评论

      • 40c6620494c9:倒数第二个,NSLog(@"1"); // 任务1
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"2"); // 任务2
        dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"3"); // 任务3
        });
        NSLog(@"4"); // 任务4
        });
        NSLog(@"5"); // 任务5
        如果我把其中的同步改成异步呢???结果你认为是什么样的
        FaiChou:@偶像MJ 在global_queue里异步获取main_queue执行任务3. 结果有15243,12543,12453。好麻烦的样子~ :scream:
      • NiubilityLeo:明白了,因为任务2,3是在4之后执行的,但是4之后已经被阻塞掉了
        FaiChou:@NiubilityLeo 很棒 :grin:
      • NiubilityLeo:倒数第一个和倒数第二个感觉矛盾啊,都一样,为什么一个阻塞了,一个没阻塞

      本文标题:iOS GCD 死锁理解

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