首先你这问题不是很严谨。你这段代码死锁的条件是,整段代码得在主线程上运行,而如果在一个其他的线程队列上运行,都是不会有问题的,不管它是串行的还是并行的。 比如这样: dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"1"); dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"2"); }); NSLog(@"3"); }); 或者这样: dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL); dispatch_async(serialQueue, ^{ NSLog(@"1"); dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"2"); }); NSLog(@"3"); }); 你上面提到的之所以会造成死锁,原因在于,你在一个串行队列中,同步的向此队列添加了一个block块。 实际上,就是这样: dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL); dispatch_async(serialQueue, ^{ NSLog(@"1"); dispatch_sync(serialQueue, ^{ NSLog(@"2"); }); NSLog(@"3"); }); 简单点说,问题在于,串行队列是串行执行的,在这个串行队列上有三个任务,分别是: NSLog(@“1”) dispatch_sync NSLog(@“3”) 在走到第2步的时候,发现需要给整个队列添加一个任务,就是 NSLog(@"2") 。这时候,执行的任务就变成了: NSLog(@“1”) dispatch_sync NSLog(@“3”) NSLog(@“2”) 然后,因为是同步的,所以: 线程就要等 NSLog(@"2") 执行完了才能往下走,去执行NSLog(@“3”)。 但是NSLog(@"2")执行之前需要执行 NSLog(@“3”)。 NSLog(@“3”)又需要等 NSLog(@"2")执行完了。 然后,就死锁了。
首先你这问题不是很严谨。你这段代码死锁的条件是,整段代码得在主线程上运行,而如果在一个其他的线程队列上运行,都是不会有问题的,不管它是串行的还是并行的。
比如这样:
或者这样:
你上面提到的之所以会造成死锁,原因在于,你在一个串行队列中,同步的向此队列添加了一个block块。
实际上,就是这样:
简单点说,问题在于,串行队列是串行执行的,在这个串行队列上有三个任务,分别是:
NSLog(@“1”)
dispatch_sync
NSLog(@“3”)
在走到第2步的时候,发现需要给整个队列添加一个任务,就是
NSLog(@"2")
。这时候,执行的任务就变成了:NSLog(@“1”)dispatch_syncNSLog(@“3”)
NSLog(@“2”)
然后,因为是同步的,所以:
线程就要等
NSLog(@"2")
执行完了才能往下走,去执行NSLog(@“3”)
。但是
NSLog(@"2")
执行之前需要执行NSLog(@“3”)
。NSLog(@“3”)
又需要等NSLog(@"2")
执行完了。然后,就死锁了。