2015-09-07 31 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

你似乎沒有仔細閱讀過這個問題。 –

相關問題