GCD线程死锁
GCD 确实好用 ,非常强大,相比NSOpretion 无法提供 取消任务的功能。
如此强大的工具用不好可能会出现线程死锁。 例如以下代码:
- (void)viewDidLoad{
[super viewDidLoad];
NSLog(@"=================4");
dispatch_sync(dispatch_get_main_queue(),
^{ NSLog(@"=================5"); });
NSLog(@"=================6");
}
GCD Queue 分为三种:
1。The main queue :主队列。主线程就是在个队列中。
2,Global queues : 全局并发队列。
3。用户队列:是用函数 dispatch_queue_create创建的自己定义队列
dispatch_sync 和 dispatch_async 差别:
dispatch_async(queue,block) async 异步队列,dispatch_async
函数会马上返回, block会在后台异步运行。
dispatch_sync(queue,block) sync 同步队列。dispatch_sync
函数不会马上返回,及堵塞当前线程,等待 block同步运行完毕。
分析上面代码:
viewDidLoad 在主线程中, 及在dispatch_get_main_queue() 中,运行到sync 时 向
dispatch_get_main_queue()插入 同步 threed。sync 会等到 后面block 运行完毕才返回, sync 又再 dispatch_get_main_queue() 队列中。它是串行队列。sync 是后加入的,前一个是主线程。所以 sync 想运行 block 必须等待主线程运行完毕,主线程等待 sync 返回。去运行兴许内容。照成死锁。sync 等待mainThread 运行完毕。 mianThread 等待sync 函数返回。以下样例:
- (void)viewDidLoad{
[super viewDidLoad];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"=================1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"=================2"); });
NSLog(@"=================3"); });
}
程序会完毕运行。为什么不会出现死锁。c语言文件
首先: async 在主线程中 创建了一个异步线程 加入 全局并发队列,async 不会等待block 运行完毕,马上返回,
1,async 马上返回, viewDidLoad 运行完毕。及主线程运行完毕。
2,同一时候。全局并发队列马上运行异步 block , 打印 1, 当运行到 sync 它会等待 block 运行完毕才返回。 及等待dispatch_get_main_queue() 队列中的 mianThread 运行完毕, 然后才开始调用block 。
由于1 和 2 差点儿同一时候运行,由于2 在全局并发队列上。 2 中运行到sync 时 1 可能已经运行完毕或 等了一会,mainThread 非常快退出。 2 等已运行后继续内容。假设堵塞了主线程,2 中的sync 就无法运行啦,mainThread 永远不会退出。 sync 就永远等待着。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-76693-7.html