我应该将 dispatch_group_leave 包装在 @synchronized 块中吗?

Should I wrap dispatch_group_leave in an @synchronized block?

给定以下代码,是否不需要 @synchronized 调用?

我假设 dispatch_group_enter/leave 是原子的,但它在这里没有被列为线程安全 https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/dispatch_group_leave.3.html 我突然担心我一直搞砸了。

// Imagine this is on its own queue already (possibly main, possibly not)
dispatch_group_t group = dispatch_group_create();
for(x in array){
  dispatch_group_enter(group);
  [x doSomethingAsync:^{
    // imagine x is part of a library which sometimes runs blocks on
    // a different queue.
    // surely dispatch_group_leave has its own internal synchronization?
    @synchronized(group){
      dispatch_group_leave(group);
    }
  }]
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

因为您没有生成线程,所以您不必担心。

在您的示例中,dispatch_group_leave(group) 是在同一个线程上调用的。

调用 dispatch_group_enterdispatch_group_leave 时不需要提供任何额外的同步。 GCD 本身提供并发和线程工具。如果需要额外的同步或障碍,我的期望是它会在文档中明确调用,就像调用 dispatch_once_ts 具有 global/static 存储的要求一样。换句话说,GCD 一个线程库,因此期望是,除非另有说明,否则它的调用应该提供相对于彼此的线程安全性。

这种期望是基于很多个人经验和格雷格·帕克 a similar statement on a mailing list 不久前做出的。