onm*_*133 4 deadlock sync dispatch grand-central-dispatch ios
dispatch_queue_t queueA; // assume we have this
dispatch_sync(queueA, ^(){ // (a)
dispatch_sync(queueA, ^(){ // (b)
foo();
});
});
Run Code Online (Sandbox Code Playgroud)
一旦我们点击了第二个dispatch_sync,我们就会死锁:我们无法调度到queueA,因为有人(当前线程)已经在该队列上并且永远不会离开它.
只要我明白
dispatch_sync只需添加工作项(我避免使用"块",因为它可能会混淆)到queueA,然后这个工作项将被发送到queueA的目标队列,然后GCD将为此工作项保留一个线程
threadWorkItem我已经阅读了很多与此相关的线程,比如使用dispatch_sync进行死锁,为什么我们不能在当前队列中使用dispatch_sync?,为什么这个dispatch_sync()调用冻结?,...但是找不到好的解释.有人说dispatch_sync阻止队列,有人说它阻止当前线程,...... :(
那为什么会导致僵局呢?
Rob*_*Rob 11
该dispatch_sync块当前线程,直到被派遣代码完成,如果你正在从同步串行队列调度,您因此被有效地阻止了队列,太.因此,如果您从串行队列同步调度到自身,则会导致死锁.
但要明确,dispatch_sync阻止当前线程,而不是当前队列.处理并发队列时,不同的工作线程将用于随后调度的块,并且不会产生死锁.
您似乎正在响应" 并发编程指南"的" 调度队列"一章末尾的讨论,其中说:
不要
dispatch_sync从传递给函数调用的同一队列上执行的任务调用该函数.这样做会使队列死锁.如果需要调度到当前队列,请使用该dispatch_async函数异步执行此操作.
这不完全正确.如果(a)您使用并发队列执行此操作; (b)有可用的工作线程,这不会导致死锁.但这是一种不好的做法,应该避免.
| 归档时间: |
|
| 查看次数: |
2516 次 |
| 最近记录: |