1

我們正在使用GCD在圖像編輯器視圖中「在背景中」執行一些圖像處理操作,效果很好。問題是如果我們打開編輯器視圖,做一些處理,然後在編輯器視圖中停留10-20分鐘,我們會得到這些OSSpinLockLock凍結,但我們沒有使用SpinLocks或任何類型的鎖,我們有這些屬性:使用Grand Central Dispatch(GCD)時獲取OSSpinLockLock

@property (nonatomic, readonly) dispatch_semaphore_t processingSemaphore; 
@property (nonatomic, readonly) dispatch_queue_t serialQueue; 

和設置隊列,像這樣:

processingSemaphore = dispatch_semaphore_create(1); 
serialQueue = dispatch_queue_create("com.myapp.imageProcessingQueue", NULL); 
dispatch_set_target_queue(serialQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, NULL)); 

和過程正是如此:

dispatch_async(self.serialQueue, ^{ 
    dispatch_semaphore_wait(self.processingSemaphore, DISPATCH_TIME_FOREVER); 

    ....<do stuff>.... 

    dispatch_semaphore_signal(self.processingSemaphore); 

    dispatch_sync(dispatch_get_main_queue(), ^{ 
     ....<notify that we're done>.... 
    }]; 
}); 

我想知道如果它的信號不知何故。

回答

0

也許不用信號量,你可以創建一個串行隊列。像這樣創建你的隊列:

serialQueue = dispatch_queue_create("com.myapp.imageProcessingQueue", DISPATCH_QUEUE_SERIAL); 

這將確保一次只能執行一個塊。

雖然您不能取消對此隊列的操作。要做到這一點,你需要使用NSOperationQueue。

+0

你是對的,如果我使用串行隊列,那麼我不應該需要一個信號量。取消是好的,我通過'_stopProcessing'布爾值來處理。 – Shizam 2013-03-08 17:28:13

2

libdispatch在隊列或信號量實現中不使用OSSpinLockLock,但malloc確實(因此Block_copy,它將libdispatch作爲dispatch_async的一部分調用)。

當你在OSSpinLockLock中被阻塞時,你能顯示所有線程的回溯嗎?

+0

下面是更多的跟蹤:http://tinyurl.com/aju9dmw – Shizam 2013-03-08 17:27:07

+1

不幸的是,相關的信息是在Xcode隱藏的中間幀。相反,在lldb(Xcode調試器控制檯)中運行'thread backtrace all'可能是最容易的。 – das 2013-03-10 00:50:07

+0

我是否正確地解釋了你的答案:將任何對象複製到塊中(通過引用塊之外的對象),這可能導致問題?即在塊內,我引用一個在主線程同時被引用的塊之外的對象。 – Shizam 2013-04-18 19:05:53

相關問題