首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >dispatch_async vs dispatch_sync执行顺序

dispatch_async vs dispatch_sync执行顺序
EN

Stack Overflow用户
提问于 2013-01-12 19:47:19
回答 2查看 7.1K关注 0票数 9

我有一个使用以下命令创建的串行调度队列:

代码语言:javascript
复制
dispatch_queue_t serialQueue = dispatch_queue_create("com.unique.name.queue", DISPATCH_QUEUE_SERIAL);

我希望使用这个串行队列来确保类访问的线程安全,同时自动异步执行不需要返回到调用线程的工作。

代码语言:javascript
复制
- (void)addObjectToQueue:(id)object
{
    dispatch_async(serialQueue, ^{
        // process object and add to queue
    }); 
}

- (BOOL)isObjectInQueue:(id)object
{
    __block BOOL returnValue = NO;
    dispatch_sync(serialQueue, ^{
        // work out return value
    });
    return returnValue;
} 

如果我调用addObjectToQueue:方法,然后立即调用isObjectInQueue:方法,它们是否保证以相同的顺序执行,或者isObjectInQueue将/是否会首先执行?

换句话说,除了不阻塞调用线程之外,dispatch_async是否与dispatch_sync完全相同(立即调度块)?

我看到过类似的问题,答案也是双向的,所以我正在寻找一个明确的答案,最好是有Apple文档支持的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-12 20:49:27

它们能保证以相同的顺序执行吗?

是。

将/可以首先执行isObjectInQueue吗?

是。

这两个答案都是肯定的原因是你应该考虑线程化。这可能就是您首先使用串行队列的原因。您正在使对队列线程的访问变得安全。

基本上,这些块将按照它们被放入串行队列的顺序执行。这是100%保证的。但是,如果多个线程都在处理这个问题,那么一个线程可能会在另一个线程有机会添加内容之前,先进入队列中读取内容。

换句话说,除了不阻塞调用线程之外,dispatch_async是否与dispatch_sync完全相同(立即调度块)?

没错。在这两种情况下,块都被添加到队列中。它会立即添加。dispatch_sync只需等待块完成,然后再返回,而dispatch_async会立即返回。

票数 13
EN

Stack Overflow用户

发布于 2013-01-12 20:47:15

我猜你的问题是,当dispatch_async仍在执行队列操作时,主线程是否会继续运行?我假设它不会,因为这将值得明确提到。如果说有什么不同的话,那就是我在dispatch_async.3中找到了这个,这表明情况是这样的:

从概念上讲,dispatch_sync()是dispatch_async()的一个方便的包装器,它添加了一个信号量来等待块的完成,以及一个包装器来通知块的完成。

实际上,如果您遵循dispatch_async in queue.c的源代码,您将看到该块在前台排队,只有在此之后,执行才会返回到调用dispatch_async的代码。因此,如果队列是串行的,则dispatch_async后跟来自同一线程的dispatch_sync 将按顺序对这些块进行排队。

因为dispatch_sync将阻塞,直到该块(以及之前在串行队列中的所有块)执行完毕,那么您的代码就是正确的。如果之前添加的对象在队列中,isObjectInQueue:将正确上报。

编辑:在多线程环境中,我会将上面的代码写成:

代码语言:javascript
复制
- (void)addObjectToQueue:(id)object
{
    dispatch_barrier_async(_queue, ^{
        // process object and add to queue
    });
}

- (BOOL)isObjectInQueue:(id)object
{
    __block BOOL returnValue = NO;
    dispatch_sync(_queue, ^{
        // work out return value
    });
    return returnValue;
} 

因为每个方法的执行可以在有利于另一个线程的任何时刻被推迟。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14293027

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档