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

相关问题