iOS基础篇-GCD死锁
2018-02-25 本文已影响207人
麦子_KB
GCD死锁概念:
使用GCD多线程编程时,如果同步函数dispatch_sync(),目标queue为当前queue,且queue为串行队列时,由于线程相互等待,会造成死锁,导致程序奔溃。
主线程运行如下代码:奔溃
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"queue");
});
或者:
// 串行队列
dispatch_queue_t queue = dispatch_queue_create("test.concurrent", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
dispatch_sync(queue, ^{
NSLog(@"bbb");
});
});
原因分析如下:
dispatch_sync函数的目标队列为main_queue,而当前函数所在的队列也是main_queue。函数等待main_queue里block执行完成后才返回,而block任务加在当前main_queue队尾,block在等待dispatch_sync函数执行完成,它才会执行。相互等待造成block永远都无法执行,死锁导致程序奔溃。
解决办法:
1.目标queue和函数所在queue不相同
NSLog(@"aaa");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"bbb");
});
});
NSLog(@"ccc");
2.queue为并行队列
NSLog(@"aaa");
// 并行队列
dispatch_queue_t queue = dispatch_queue_create("test.concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
dispatch_sync(queue, ^{
NSLog(@"bbb");
});
});
NSLog(@"ccc");