GCD dispatch_sync 优先于先前排队的 dispatch_async

Posted

技术标签:

【中文标题】GCD dispatch_sync 优先于先前排队的 dispatch_async【英文标题】:GCD dispatch_sync priority over previously queued dispatch_async 【发布时间】:2014-11-07 18:09:44 【问题描述】:

我有一个包装数据模型并由多个线程访问/修改的类。我需要确保对数据模型的修改是同步的。我正在使用 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 个“异步任务”排队,其中一个正在执行。现在安排了“同步”任务。 “同步任务”什么时候执行?

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

顺便说一句,

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

【问题讨论】:

【参考方案1】:

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

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 移动到块本身。

【讨论】:

感谢您的回复。这看起来是个不错的解决方案。我会实施它并让你知道它是如何进行的。 我已经实现了它并对其进行了很多测试,并且完全符合我的需要。

以上是关于GCD dispatch_sync 优先于先前排队的 dispatch_async的主要内容,如果未能解决你的问题,请参考以下文章

dispatch_sync:As an optimization, this function invokes the block on the current thread when possibl

UIPanGestureRecognizer 是不是优先于 -touchesMoved: 方法?

为啥导入的类优先于捆绑类?

为啥正文中的 javascript 函数优先于头部中的函数?

Java:Effective java学习笔记之 列表优先于数组

在 Python 中,为啥属性优先于实例属性?