如果dispatch_async
队列上的代码块当前被它自己的dispatch_sync
操作阻塞,会发生什么?他们会锁定还是在dispatch_sync
操作返回后阻塞的队列会继续?
我创建了一个对象,用于管理对后备存储(在本例中为 SQLite)的访问。它使用一个concurrent
GCD 队列,任何其他想要从存储中访问信息的对象都会向管理器传递一个请求以及一个异步执行的块。发生的事情的本质是这样的(不是实际的代码):
- (void) executeRequest:(StoreRequest *)request withCompletionBlock:(void(^)(NSInteger result)block{
dispatch_queue_t currentContext = dispatch_get_current_queue();
dispatch_async(_storeQueue, ^{
NSInteger result = [_store executeRequest:request];
if (block){
dispatch_async(currentContext, ^{
block(result);
}
}
});
}
真正的代码有点复杂(我实际上排队并存储请求/块/上下文以在运行循环结束时执行)。我还dispatch_barrier_async
用于写请求以防止并发读/写。这一切都很好,但在某些情况下,我还需要在商店上执行同步请求。现在这个请求不需要在任何排队操作之前执行,但我确实需要阻塞请求队列,直到执行操作。这很容易做到:
- (NSInteger) executeRequest:(StoreRequest *)request{
__block NSInteger result = 0;
dispatch_sync(_storeQueue, ^{
result = [_store executeRequest:request];
});
return result;
}
我的问题是:如果放置在同步操作之前的未决异步操作在当前被同步调度阻塞的队列上异步调度代码块,会发生什么情况。换句话说,上述操作将在_store
队列末尾分派其请求并等待。但是很可能(甚至很可能)它前面的操作包括异步分派回等待队列(用于其他操作)。这会锁定线程吗?由于排队的块是异步调度的_store
队列永远不会被阻塞,因此将完成,理论上允许它阻塞的队列继续......但我不确定异步分派的块会发生什么,或者是否将任何内容分派给块线程会将其锁定。我会假设被阻塞的队列将继续,完成它的请求,然后处理待处理的块,但我想确定一下。
实际上,既然我已经写了这一切,我很确定它会正常工作,但无论如何我都会发布这个问题以确保我没有遗漏任何东西。