使用Grand Central Dispatch(GCD)时获取OSSpinLockLock

时间:2013-03-07 20:43:25

标签: ios multithreading cocoa-touch thread-safety grand-central-dispatch

我们正在使用GCD在我们的图像编辑器视图中“在后台”执行一些图像处理操作,效果很好。问题是,如果我们打开编辑器视图,进行一些处理,然后只需在编辑器视图中坐10-20分钟就可以得到这些OSSpinLockLock冻结,但我们没有使用SpinLocks或锁定任何一种,我们都有这些属性:

@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>....
    }];
});

我想知道它的信号量是否以某种方式。

2 个答案:

答案 0 :(得分:2)

libdispatch在队列或信号量实现中不使用OSSpinLockLock,但是malloc确实如此(因此,block_copy,libdispatch调用它作为dispatch_async的一部分)。

当您在OSSpinLockLock中被阻止时,是否可以显示所有线程的回溯?

答案 1 :(得分:0)

也许您可以创建一个串行队列而不是使用信号量。像这样创建你的队列:

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

这将确保一次只执行一个块。

但您无法取消此队列上的操作。为此,您需要使用NSOperationQueue。