繁体   English   中英

dispatch_async块未被调用

[英]dispatch_async block not called

我遇到了一个我以前从未见过的问题。 我从未想过它可能会存在。 我正在使用DFCache库,并且在某个时刻dispatch_async使用全局队列不执行块。

- (void)cachedObjectForKey:(NSString *)key completion:(void (^)(id))completion {
if (!key.length) {
    _dwarf_cache_callback(completion, nil);
    return;
}
id object = [self.memoryCache objectForKey:key];
if (object != nil) {
    _dwarf_cache_callback(completion, object);
    return;
}

NSLog(@"Before calling async %d queue %p", [NSThread isMainThread], _processingQueue);

dispatch_async(_processingQueue, ^{
     NSLog(@"Block called");

    @autoreleasepool {


        id object = [self _cachedObjectForKey:key];
        _dwarf_cache_callback(completion, object);
    }
});

}

这是这个队列的创建方式:

 _processingQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

队列永远不会在任何其他地方使用。 这不是我的代码。 这是DFCache库的代码。 但是我的代码中有一些东西会影响队列,因为它总是在特定时刻停止工作。 我加载,保存,加载,保存,加载......不调用块。 但我不明白为什么。 我需要知道什么可能导致在dispatch_async上没有调用块。 我的代码是如此庞大和复杂,所以我不在这里发布。 我需要的是一个提示。 具体原因可能导致这种行为? 你有没有看到dispatch_async没有在全局队列中调用它的块? 是什么造成的?

如果您在日志消息中看到“在调用异步之前...”但没有“阻止调用”,则可能的情况是所有线程都在全局队列中被阻止。

例如,以下代码应无限打印“Block called”,但不能。

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(q, ^{
    while (YES) {
        dispatch_async(q, ^{
            NSLog(@"Block called\n");

            // BLOCK THE THREAD
            while (YES)
                ;
        });
    }
});

系统为全局队列准备了一个线程池。 池中的线程数可能因运行时状态而异,但无论如何,线程数都是有限的。 最终,所有线程都将被无限循环阻塞。

因此,您的代码可能会有一些死锁,无限循环或一些阻塞全局队列线程的东西。

原因就像方法( cachedObjectForKey )在执行dispatch_async之前返回。 我们可以看到

if (object != nil) {
  _dwarf_cache_callback(completion, object);
   return; // this might be the reason for not calling of dispatch_async
}

如果key.length不存在,代码中还有一个return

希望这可以帮助

就我而言,我们更新了一堆第三方库,这种情况开始发生。 暂停应用程序并分析线程,有几个TapStream'内部线程'等待实例。 我禁用了TapStream,这个问题就消失了。 对我来说,为什么它的内部线程会阻塞全局队列仍然没有意义......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM