最近,我需要一个函数来保证在特定串行调度队列上同步执行给定块。有可能这个共享函数可以从已经在该队列上运行的东西中调用,所以我需要检查这种情况,以防止同步分派到同一个队列时出现死锁。
我使用如下代码来执行此操作:
void runSynchronouslyOnVideoProcessingQueue(void (^block)(void))
{
dispatch_queue_t videoProcessingQueue = [GPUImageOpenGLESContext sharedOpenGLESQueue];
if (dispatch_get_current_queue() == videoProcessingQueue)
{
block();
}
else
{
dispatch_sync(videoProcessingQueue, block);
}
}
此函数依赖于使用dispatch_get_current_queue()
来确定运行此函数的队列的身份,并将其与目标队列进行比较。如果匹配,它知道只运行块内联而不调度到该队列,因为函数已经在其上运行。
dispatch_get_current_queue()
我听说过关于使用这样的比较是否合适的相互矛盾的事情,我在标题中看到了这样的措辞:
建议仅用于调试和记录目的:
代码不得对返回的队列做出任何假设,除非它是全局队列之一或代码自己创建的队列。如果该队列不是 dispatch_get_current_queue() 返回的队列,则代码不能假定在队列上同步执行不会出现死锁。
此外,在 iOS 6.0 中(但尚不支持 Mountain Lion),GCD 标头现在将此功能标记为已弃用。
听起来我不应该以这种方式使用此功能,但我不确定应该使用什么来代替它。对于像上面这样针对主队列的函数,我可以使用[NSThread isMainThread]
,但是如何检查我是否在我的自定义串行队列之一上运行,以便防止死锁?