2015-09-07 35 views
0

我有一段代码,我只想一次运行一次。如果它同时运行不止一次,它不是世界的尽头,但是它占用了资源,这就是问题所在。我们称之为HEAVY_STUFF。有没有更优雅的方式避免在GCD队列上等待调度?

问题是我的所有任务都依赖于HEAVY_STUFF在完成后至少运行一次。最多可以有2000个任务,并且会在所有2000个任务完全同时完成的情况下发生。通常我只是使用dispatch_group_notify或类似的,但这意味着HEAVY_STUFF只运行一次就运行2000次。此外,它还要求1999年的线程不要等待,因为它们拥有大量内存 - 例如,如果1999年的线程处于等待发送状态,那么即使仔细的autoreleasepool包装,我们的iPhone 5S也会消耗> 300MB。哎哟。

下面是我现在正在解决它。我不确定它是线程安全的,但似乎工作到目前为止 - 内存使用量保持在35MB左右,HEAVY_STUFF在每个任务完成后至少运行一次。这是线程安全的吗?什么是更好的GCD解决方案?我不想使用NSOperation *。

static int counter = 0; 

- (void)taskCompleted { 
    // can be called 2000 times from 2000 different threads, all at once 

    if(counter > 0) { 
     return; 
    } 

    OSAtomicIncrement32Barrier(&counter); 

    dispatch_group_async(self.group, self.queue, ^{ 

     OSAtomicDecrement32Barrier(&counter); 
     if(counter > 0) { 
      return; 
     } 

     HEAVY_STUFF 
    }); 
} 

感谢您的帮助。

+1

为什么'dispatch_group_notify()'让你的完成例程运行多次?你是否将所有任务添加到同一组? –

+0

@JoshCaswell不幸的是,这些任务都是同一组的一部分。我不能使用_notify(),因为然后直到1999年线程阻塞并吃了300MB的内存。 – xaphod

+0

这不应该是'dispatch_group_notify()'的工作方式。个人任务应该自行完成。 –

回答

-1

这是线程安全的只运行一次:

static dispatch_once_t onceToken; 
     dispatch_once(&onceToken, ^{ 

     }); 
+1

你似乎没有仔细阅读过这个问题。 –

相关问题