美文网首页
iOS:GCD死锁

iOS:GCD死锁

作者: 春暖花已开 | 来源:发表于2019-04-08 15:18 被阅读0次

出现死锁的特点:sync函数,向 当前 串行队列 添加任务。

举例:

@implementation ViewController

- (void)test1 {
   
    dispatch_queue_t queue = dispatch_queue_create("mz_01", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        NSLog(@"111");
        [self performSelector:@selector(mySelector) withObject:nil afterDelay:.0];
        //如果不开启runloop,那么只会打印 111 333
        //原因是`performSelector:withObject:afterDelay:`相当于开启一个定时器,但子线程默认是不开启定时器的
        //[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        NSLog(@"333");
    });
}

- (void)test2 {
    
    NSThread *thread = [[NSThread alloc] initWithBlock:^{
        NSLog(@"111");
        //如果不加这两行代码,则会crash
        //原因是执行完block的代码,线程就退出了,加上这两句代码使线程保活(保活和变量thread内存释放不是一个概念)
        //[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
        //[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }];
    [thread start];
    
    [self performSelector:@selector(mySelector) onThread:thread withObject:nil waitUntilDone:YES];
}

//死锁
- (void)test3 {
    
    NSLog(@"111");
    //当前队列是main
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"222");
    });
    NSLog(@"333");
}

//不会死锁
- (void)test4 {
    
    NSLog(@"111");
    //dispatch_async: 不要求立马执行block
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"222");
    });
    NSLog(@"333");
}

//死锁
- (void)test5 {
    //使用 `sync` 函数向`当前` `串行`队列添加任务,会死锁
    dispatch_queue_t queue = dispatch_queue_create("mz_03", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
            //dispatch_sync表示马上在当前线程执行任务
        dispatch_sync(queue, ^{
            NSLog(@"111--%@", [NSThread currentThread]);
        });
        NSLog(@"222--%@", [NSThread currentThread]);
    });
    NSLog(@"333");
}

//不死锁
- (void)test6 {
    
    dispatch_queue_t queue = dispatch_queue_create("mz_03", DISPATCH_QUEUE_SERIAL);
    //当前队列是main
    dispatch_sync(queue, ^{
        NSLog(@"111--%@", [NSThread currentThread]);
    });
    NSLog(@"222");
}

//不死锁
- (void)test7 {
    
    dispatch_queue_t queue = dispatch_queue_create("serialQueue",DISPATCH_QUEUE_SERIAL);
    NSLog(@"1");

    dispatch_async(queue,^{
        NSLog(@"2");
        //虽然是用sync函数向串行队列添加任务,但由于不是往当前queue里添加,故不会死锁
        dispatch_sync(dispatch_get_main_queue(),^{
            NSLog(@"3");
        });
        NSLog(@"4");
    });
    NSLog(@"5");
}

- (void)mySelector {
    NSLog(@"222");
}

@end

相关文章

网友评论

      本文标题:iOS:GCD死锁

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