我有一个使用以下命令创建的串行调度队列:
dispatch_queue_t serialQueue = dispatch_queue_create("com.unique.name.queue", DISPATCH_QUEUE_SERIAL);我希望使用这个串行队列来确保类访问的线程安全,同时自动异步执行不需要返回到调用线程的工作。
- (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文档支持的。
发布于 2013-01-12 20:49:27
它们能保证以相同的顺序执行吗?
是。
将/可以首先执行
isObjectInQueue吗?
是。
这两个答案都是肯定的原因是你应该考虑线程化。这可能就是您首先使用串行队列的原因。您正在使对队列线程的访问变得安全。
基本上,这些块将按照它们被放入串行队列的顺序执行。这是100%保证的。但是,如果多个线程都在处理这个问题,那么一个线程可能会在另一个线程有机会添加内容之前,先进入队列中读取内容。
换句话说,除了不阻塞调用线程之外,dispatch_async是否与
dispatch_sync完全相同(立即调度块)?
没错。在这两种情况下,块都被添加到队列中。它会立即添加。dispatch_sync只需等待块完成,然后再返回,而dispatch_async会立即返回。
发布于 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:将正确上报。
编辑:在多线程环境中,我会将上面的代码写成:
- (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;
} 因为每个方法的执行可以在有利于另一个线程的任何时刻被推迟。
https://stackoverflow.com/questions/14293027
复制相似问题