在苹果的文档,它说:如何在Grand Central Dispatch中创建死锁?
要点:你不应该叫dispatch_sync或从在同一队列执行任务dispatch_sync_f 功能,你是 规划传递给函数。这对保证死锁的 串行队列尤为重要,但对于并发队列也应避免 。
你如何编写代码来做到这一点?
创建在苹果的文档,它说:如何在Grand Central Dispatch中创建死锁?
要点:你不应该叫dispatch_sync或从在同一队列执行任务dispatch_sync_f 功能,你是 规划传递给函数。这对保证死锁的 串行队列尤为重要,但对于并发队列也应避免 。
你如何编写代码来做到这一点?
创建的在某个队列故意僵局:
dispatch_queue_t queue = dispatch_queue_create("my.label", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
dispatch_sync(queue, ^{
// outer block is waiting for this inner block to complete,
// inner block won't start before outer block finishes
// => deadlock
});
// this will never be reached
});
很明显,这里说的外部和内部的块在同一个队列操作。发生这种情况的大多数情况是在那些不太明显dispatch_sync
的调用者正在操作的队列中的哪个位置。这通常发生在一个(深)嵌套堆栈中,在这个堆栈中,您正在某个队列中初始启动的某个类中执行代码,并且偶然会将dispatch_sync
调用到同一个队列中。
当发生死锁时...... UI不应该没有反应? – BlackMouse 2013-03-13 09:46:58
@ user1251004只有在主队列被阻塞的情况下。 – 2013-03-13 09:49:13
在这个例子中,只有创建的'queue'被阻塞。主队列继续运行。 – 2013-03-13 10:04:15
简单的代码僵局:
dispatch_queue_t q = dispatch_queue_create("deadlock queue", DISPATCH_QUEUE_SERIAL);
NSLog(@"1");
dispatch_async(q, ^{
NSLog(@"2");
dispatch_sync(q, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
日志输出:
1
5
2
这里内部块定于串行队列q
运行,但它不能运行,直到当前块已经结束了,当前块反过来等待内部完成,因为我们同时调用它。
到块的最简单方法是将dispatch_sync
在当前队列:
dispatch_sync(dispatch_get_current_queue(), ^{});
此块在当前队列是一个串行队列,例如主队列。
在最新斯威夫特语法:
let queue = DispatchQueue(label: "label")
queue.async {
queue.sync {
// outer block is waiting for this inner block to complete,
// inner block won't start before outer block finishes
// => deadlock
}
// this will never be reached
}
你想例如,创建死锁的代码? – Vladimir 2013-03-13 09:23:36
是的请为学习 – BlackMouse 2013-03-13 09:28:35
另请参见[这个问题](http://stackoverflow.com/questions/10330679/how-to-dispatch-on-main-queue-synchronously-without-a-deadlock)为一个现实的例子那很容易出现死锁。 – zoul 2013-03-13 09:42:37