dispatch_group_wait 允许插队吗?

Does dispatch_group_wait allow cutting in line?

这个问题是关于 Grand Central Dispatch 的,特别是 dispatch_group_wait()

假设一个名为 groupdispatch_group 中有 10 个任务等待执行。

在其他地方,我有一个任务需要等待 group 中的任何任务完成才能执行。为了做到这一点,我使用 dispatch_group_wait(group, DISPATCH_TIME_FOREVER).

为了区别于group中的任务,我将其称为lonelyTask

如果在 lonelyTask 等待时另一个任务被添加到 group,哪个先执行,lonelyTask 还是添加到 group 的任务?换句话说,在另一个任务等待执行时添加到 group 的任务是否先于等待任务执行 "cut in line",或者它们被调用的顺序是否保持不变?

我已经搜索了文档,但没能找到这个问题的答案...

dispatch_group_waitdispatch_group_notify都在等待入组的item数过渡到0。因此,如果您在原始十个任务全部完成之前将第十一个任务添加到组中,则对 dispatch_group_wait 的调用将等待所有十一个任务完成后再继续。

Group 是一个 +/- 计数器(信号量),每次达到零时都会触发。它不知道任务,因为 dispatch_group_async() 只是一个包装器,它在任务提交之前进入 ()s 组,并将一个新块排入队列,该块将调用任务的块,然后离开 () 该组。就这样。组甚至可以在没有队列的情况下用作异步保留计数器或 sml。

所以一般来说"you can't"。

但是,如果您能够将所有相关队列 [re] 定位 (dispatch_set_target_queue()) 到一个并发队列,那么该队列上的 dispatch_barrier_async() 可能会执行您想要的操作,如果以适当的隔离方式调用。请注意,该组与此完全无关。

此外,从组的角度来看,原始的 lonelyTask 不是任务 — 它是等待组平衡的不相关的执行线程。 "cutting in line" 的同义词是 "barrier"。


另一种方法是为每个任务集创建一个私有组并等待该特定组。但这不会插入障碍——后续任务不会等待 lonelyTask 完成,任何不受控制的 async()s 可能 "break the rules",导致有趣的调试会话。