1

我们正在使用 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>....
    }];
});

我想知道它是否是某种信号量。

4

2 回答 2

2

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

当你被 OSSpinLockLock 阻塞时,你能显示所有线程的回溯吗?

于 2013-03-08T04:55:06.260 回答
0

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

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

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

但是,您不能取消对此队列的操作。为此,您需要使用 NSOperationQueue。

于 2013-03-07T20:53:48.603 回答