我遇到的情况是我想确保两个队列最终在不同的线程上执行。理想情况下,我想确保它们是串行队列。特别是,在下面的示例中,如果两个队列都在同一个线程上运行,那么doStuff将无限期地忙着等待。我是否必须转向显式线程,或者我可以在这里挽救使用GCD吗?
- (void)foo {
self.responseQueue = dispatch_queue_create("com.blah.response", DISPATCH_QUEUE_SERIAL);
self.requestQueue = dispatch_queue_create("com.blah.request", DISPATCH_QUEUE_SERIAL);
dispatch_async(self.requestQueue, ^{
[self doStuff];
});
}
- (BOOL)doStuff {
BOOL __block waiting = YES;
self.responseBlock = ^{
waiting = NO;
};
[self performRequest];
while (waiting) {
// realize could use dispatch_semaphore (busy waiting just to illustrate point).
sleep(1);
}
[self doStuffRequiringResponseCompletion];
// I realize it would be sensible to
// 1) Not block in the above while loop.
// 2) Call |doStuffRequiringResponseCompletion| after |receivedResponse|.
// I don't want to do this.
}
// method called on arbitrary thread
- (void)receivedResponse {
// stuff
dispatch_async(self.responseQueue, self.responseBlock);
}
另请参阅:Is there any reason to not use sleep in a Grand Central Dispatch queue??
答案 0 :(得分:1)
您无法确保它们在不同的线程上运行 - 调度队列的重点是操作系统为您管理线程。但是,除非您正在进行一些非常专业的工作,而且确实要求您在特定线程上运行,否则串行调度队列的默认行为应该对您有用。如果你确实需要确保特定的线程,那么你就回到了使用NSThread。
答案 1 :(得分:1)
调度队列未绑定到线程。如果您的某个调度项阻塞了某个线程,GCD将使用或创建其他线程来处理其他队列(以及此队列中的其他项,如果它是并发队列)。
GCD将创建的线程数有一个上限。如果您有太多像这样睡觉的调度项目,那么您可能会遇到该限制并可能陷入僵局。
答案 2 :(得分:0)
你应该避免阻止线程。在您的响应块中使用您的示例,在处理响应之后,您可以将另一个块排入com.blah.request,以执行您正在等待的任何操作。