如何确保两个gcd队列在不同的线程上运行?

时间:2013-07-15 23:38:16

标签: objective-c grand-central-dispatch

我遇到的情况是我想确保两个队列最终在不同的线程上执行。理想情况下,我想确保它们是串行队列。特别是,在下面的示例中,如果两个队列都在同一个线程上运行,那么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?

3 个答案:

答案 0 :(得分:1)

您无法确保它们在不同的线程上运行 - 调度队列的重点是操作系统为您管理线程。但是,除非您正在进行一些非常专业的工作,而且确实要求您在特定线程上运行,否则串行调度队列的默认行为应该对您有用。如果你确实需要确保特定的线程,那么你就回到了使用NSThread。

答案 1 :(得分:1)

调度队列未绑定到线程。如果您的某个调度项阻塞了某个线程,GCD将使用或创建其他线程来处理其他队列(以及此队列中的其他项,如果它是并发队列)。

GCD将创建的线程数有一个上限。如果您有太多像这样睡觉的调度项目,那么您可能会遇到该限制并可能陷入僵局。

答案 2 :(得分:0)

你应该避免阻止线程。在您的响应块中使用您的示例,在处理响应之后,您可以将另一个块排入com.blah.request,以执行您正在等待的任何操作。