Multithreading GCD调度\u同步优先于先前排队的调度\u异步

Multithreading GCD调度\u同步优先于先前排队的调度\u异步,multithreading,grand-central-dispatch,Multithreading,Grand Central Dispatch,我有一个封装数据模型的类,它由多个线程访问/修改。我需要确保对数据模型的修改是同步的。我正在使用调度队列创建(…,调度队列)。这真的很适合我的需要 我的类中的大多数方法在内部调用“dispatch_async(queue,^{…});”。有几个地方需要返回快照结果。这是一个简化的示例,展示了它的外观: - (NSArray*) getSomeData { __block NSArray* result = nil; dispatch_sync(queue, ^{

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

我的类中的大多数方法在内部调用“dispatch_async(queue,^{…});”。有几个地方需要返回快照结果。这是一个简化的示例,展示了它的外观:

- (NSArray*) getSomeData {
    __block NSArray* result = nil;

    dispatch_sync(queue, ^{
         ... Do Stuff ...
         result = blah.blah;
    }

    return result;
}
现在,假设5个“异步任务”已排队,其中一个正在执行。现在计划了一个“同步”任务。“同步任务”何时执行

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

顺便说一句


我知道我可以设置总体队列优先级,但这不是这个问题的重点。对我来说,队列优先级正常就可以了。我只希望同步任务发生在任何挂起的异步任务之前。

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

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);
realQueue=dispatch\u queue\u create(NULL,dispatch\u queue\u SERIAL);
asyncOpsQueue=dispatch\u queue\u create(空,dispatch\u queue\u SERIAL);
调度\设置\目标\队列(异步操作队列,realQueue);
对于(整数i=0;i<10;i++)
{
dispatch\u async(asyncOpsQueue^{
NSLog(@“执行异步工作块%@”,@(i));
睡眠(1);
});
}
//然后,每当您有高优先级的同步工作要做时,停止异步
//排队,完成工作,然后重新启动。
调度挂起(异步操作);
调度同步(realQueue^{
NSLog(@“执行同步工作块”);
});
发送/恢复(异步操作);

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

感谢您的响应。这看起来是一个很好的解决方案。我将实现它,并让您知道它是如何运行的。我已经实现了它,并对它进行了大量测试,并且完全满足了我的需要。