GCD dispatch_sync优先级高于先前排队的dispatch_async



我有一个类,它封装了一个数据模型,并由多个线程访问/修改。我需要确保对数据模型的修改是同步的。我正在使用dispatch_queue_create(…,dispatch_queue_SERIAL)。这真的很适合我的需要。

我的类中的大多数方法内部调用"dispatch_async(queue,^{…});"。在一些地方我需要返回快照结果。这是一个简化的例子:

- (NSArray*) getSomeData {
    __block NSArray* result = nil;
    dispatch_sync(queue, ^{
         ... Do Stuff ...
         result = blah.blah;
    }
    return result;
}

现在,让我们假设有5个"异步任务"排队,其中一个正在执行。现在安排了一个"同步"任务。"同步任务"何时执行?

我希望在任何挂起的"异步任务"之前执行"同步任务"。这是默认情况吗?如果没有,是否有方法对"同步任务"进行优先级排队?

BTW,

我知道我可以设置一个整体队列优先级,但这不是这个问题的意义所在。对我来说,正常的队列优先级很好。我只希望同步任务发生在任何挂起的异步任务之前。

没有"先执行同步任务"或设置单个队列中排队块之间的相对优先级的通用设置。概括一下显而易见的情况,串行队列将像队列一样工作:先进先出。也就是说,很容易想象如何使用多个队列和目标来实现这种效果。例如:

realQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
asyncOpsQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(asyncOpsQueue, realQueue);
for (NSUInteger i = 0; i < 10; i++)
{
    dispatch_async(asyncOpsQueue, ^{
        NSLog(@"Doing async work block %@", @(i));
        sleep(1);
    });
}
// Then whenever you have high priority sync work to do, stop the async
// queue, do your work, and then restart it.
dispatch_suspend(asyncOpsQueue);
dispatch_sync(realQueue, ^{
    NSLog(@"Doing sync work block");
});
dispatch_resume(asyncOpsQueue);

需要知道的一件事是,执行块一旦开始,就不能有效地取消/挂起/终止(从外部)。因此,在同步块开始之前,任何正在运行的异步排队块都必须运行到完成,但这种定向安排允许您暂停异步块的流并注入同步块。请注意,您正在执行同步块也不重要。它可以很容易地成为一个高优先级的异步块,但在这种情况下,您可能希望将dispatch_resume移动到块本身中。

最新更新