我有一段代码,我只想一次运行一次。如果它同时运行不止一次,它不是世界的尽头,但是它占用了资源,这就是问题所在。我们称之为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
});
}
感谢您的帮助。
为什么'dispatch_group_notify()'让你的完成例程运行多次?你是否将所有任务添加到同一组? –
@JoshCaswell不幸的是,这些任务都是同一组的一部分。我不能使用_notify(),因为然后直到1999年线程阻塞并吃了300MB的内存。 – xaphod
这不应该是'dispatch_group_notify()'的工作方式。个人任务应该自行完成。 –