首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >`_dispatch_barrier_sync_f_invoke`和`_dispatch_barrier_sync_f_slow`是做什么的?

`_dispatch_barrier_sync_f_invoke`和`_dispatch_barrier_sync_f_slow`是做什么的?
EN

Stack Overflow用户
提问于 2016-12-08 22:07:43
回答 1查看 1.5K关注 0票数 2

因此,我的应用程序目前可能处于发出网络请求的状态,而当第一个请求仍在等待响应时,可以发出另一个相同的请求。

至少我觉得。根据这个逻辑,看起来线程11首先旋转,然后线程13,然后线程13看起来在等待,因为Thread 11仍然在等待响应

线程11拥有:_dispatch_barrier_sync_f_invoke,线程13拥有:_dispatch_barrier_sync_f_slow

代码语言:javascript
运行
复制
Thread 11 Crashed:
0   libsystem_kernel.dylib               0x00007fffab4d1dda __pthread_kill + 10
1   libsystem_c.dylib                    0x00007fffab437440 abort + 129
2   CrashReporter                        0x000000010f28d851 uncaught_exception_handler (PLCrashReporter.m:365)
3   CoreFoundation                       0x00007fff963d7e29 __handleUncaughtException + 745
4   libobjc.A.dylib                      0x00007fffaaac9b85 _ZL15_objc_terminatev + 94
5   libc++abi.dylib                      0x00007fffa9fbdd69 _ZSt11__terminatePFvvE + 8
6   libc++abi.dylib                      0x00007fffa9fbdde3 _ZSt9terminatev + 51
7   libobjc.A.dylib                      0x00007fffaaac998e objc_terminate + 9
8   libdispatch.dylib                    0x00007fffab36d13c _dispatch_client_callout + 28
9   libdispatch.dylib                --->0x00007fffab36dd62 _dispatch_barrier_sync_f_invoke + 83
10  Snagit                               0x000000010e1a5d68 -[AFURLSessionManager dataTaskWithRequest:completionHandler:] (AFURLSessionManager.m:664)
11  Snagit                               0x000000010e19083e -[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:success:failure:] (AFHTTPSessionManager.m:243)
12  Snagit                               0x000000010e18fb0d -[AFHTTPSessionManager GET:parameters:success:failure:] (AFHTTPSessionManager.m:112)
13  Snagit                               0x000000010e1d2f29 __51-[TSCAccountHTTPSession GET:parameters:completion:]_block_invoke (TSCAccountHTTPSession.m:317)
14  Snagit                               0x000000010e1d464f __58-[TSCAccountHTTPSession performNetworkRequest:completion:]_block_invoke_2 (TSCAccountHTTPSession.m:495)
15  libdispatch.dylib                    0x00007fffab375f5f _dispatch_call_block_and_release + 12
16  libdispatch.dylib                    0x00007fffab36d128 _dispatch_client_callout + 8
17  libdispatch.dylib                    0x00007fffab37c2ce _dispatch_queue_override_invoke + 743
18  libdispatch.dylib                    0x00007fffab36eee0 _dispatch_root_queue_drain + 476
19  libdispatch.dylib                    0x00007fffab36ecb7 _dispatch_worker_thread3 + 99
20  libsystem_pthread.dylib              0x00007fffab5b9746 _pthread_wqthread + 1299
21  libsystem_pthread.dylib              0x00007fffab5b9221 start_wqthread + 13




Thread 13:
0   libsystem_kernel.dylib               0x00007fffab4d23b6 __ulock_wait + 10
1   libdispatch.dylib                    0x00007fffab385c6e _dispatch_thread_event_wait_slow + 85
2   libdispatch.dylib                --->0x00007fffab3785ea _dispatch_barrier_sync_f_slow + 402
3   Snagit                               0x000000010e1a5d68 -[AFURLSessionManager dataTaskWithRequest:completionHandler:] (AFURLSessionManager.m:664)
4   Snagit                               0x000000010e19083e -[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:success:failure:] (AFHTTPSessionManager.m:243)
5   Snagit                               0x000000010e18fb0d -[AFHTTPSessionManager GET:parameters:success:failure:] (AFHTTPSessionManager.m:112)
6   Snagit                               0x000000010e1d2f29 __51-[TSCAccountHTTPSession GET:parameters:completion:]_block_invoke (TSCAccountHTTPSession.m:317)
7   Snagit                               0x000000010e1d464f __58-[TSCAccountHTTPSession performNetworkRequest:completion:]_block_invoke_2 (TSCAccountHTTPSession.m:495)
8   libdispatch.dylib                    0x00007fffab375f5f _dispatch_call_block_and_release + 12
9   libdispatch.dylib                    0x00007fffab36d128 _dispatch_client_callout + 8
10  libdispatch.dylib                    0x00007fffab37c2ce _dispatch_queue_override_invoke + 743
11  libdispatch.dylib                    0x00007fffab36eee0 _dispatch_root_queue_drain + 476
12  libdispatch.dylib                    0x00007fffab36ecb7 _dispatch_worker_thread3 + 99
13  libsystem_pthread.dylib              0x00007fffab5b9746 _pthread_wqthread + 1299
14  libsystem_pthread.dylib              0x00007fffab5b9221 start_wqthread + 13

下面是包含AFNetworking的dispatch_sync代码

代码语言:javascript
运行
复制
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
                            completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
    __block NSURLSessionDataTask *dataTask = nil;
   dispatch_sync(
      url_session_manager_creation_queue(), ^{
         dataTask = [self.session dataTaskWithRequest:request];
      }
   );

    [self addDelegateForDataTask:dataTask completionHandler:completionHandler];

    return dataTask;
}

static dispatch_queue_t url_session_manager_creation_queue() {
    static dispatch_queue_t af_url_session_manager_creation_queue;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        af_url_session_manager_creation_queue = dispatch_queue_create("com.alamofire.networking.session.manager.creation", DISPATCH_QUEUE_SERIAL);
    });

    return af_url_session_manager_creation_queue;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-06 03:23:42

我希望下面能回答你的问题。但是,如果您的程序中有一个要调试的错误,并且相同的请求被发出了两次,这是事实,那么这不是包含错误的代码。

GCD使用所谓的屏障来同步调度队列上的块,请看这里的文档:派单异步

屏障确保队列上的屏障块相互排斥,即它单独执行。

调度屏障允许您在并发调度队列中创建同步点。当遇到障碍时,并发队列会延迟屏障块(或任何其他块)的执行,直到所有块在屏障完成执行之前提交。在这一点上,屏障块自行执行。完成后,队列将恢复其正常执行行为。

如果队列是串行的,或者是全局并发队列,那么:

来自dispatch_barrier_sync:如果传递给该函数的队列是一个串行队列或一个全局并发队列,则此函数的行为类似于dispatch_sync函数。

实际上,dispatch_sync委托给dispatch_barrier_sync_*,调用堆栈看起来如下所示:

代码语言:javascript
运行
复制
// some inline functions omitted here
_dispatch_barrier_sync_f_invoke
_dispatch_barrier_sync_f
dispatch_sync_f
dispatch_sync

现在,如果运行时沿途无法获得另一个块的当前线程的屏障,那么它就走了slow路。这将为您和调用线程等待设置所有同步。在队列再次空闲的event上,线程继续执行下一个块。

基本上,它是相同的调用堆栈,但沿途有一个弯路,带有一些锁(信号量),然后返回到_dispatch_barrier_sync_f_invoke

代码语言:javascript
运行
复制
// again, some inline functions omitted here
_dispatch_barrier_sync_f_invoke
_dispatch_thread_event_wait
_dispatch_barrier_sync_f_slow
// here _dispatch_queue_try_acquire_barrier_sync fails...
_dispatch_barrier_sync_f
dispatch_sync_f
dispatch_sync

如果您想了解更多关于GCD__的知识,那么最好的了解内部机制的地方是它的源代码https://github.com/apple/swift-corelibs-libdispatch

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41049700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档