iOS多线程——GCD底层探索上

准备

开源的libdispatch下载地址

  • 创建4个队列,并打印查看每个队列
// 创建一个串行队列 
dispatch_queue_t queue1 = dispatch_queue_create("queue1", DISPATCH_QUEUE_SERIAL);
// 创建一个并发队列
dispatch_queue_t queue2 = dispatch_queue_create("queue2", DISPATCH_QUEUE_CONCURRENT);
// 获取主队列
dispatch_queue_t main = dispatch_get_main_queue();
// 获取全局并发队列
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
NSLog(@"%@-%@-%@-%@",queue1 ,queue2,main,globalQueue);

打印结果:

请添加图片描述

如何查找 GCD 源码

来到工程,我们跳转查看dispatch_async如下:只是提供了一个对外的接口。

#ifdef __BLOCKS__
API_AVAILABLE(macos(10.6), ios(4.0))
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
void
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
#endif

所以我们再去断点调试:
请添加图片描述

在两个符号断点dispatch_queue_create 和dispatch_sync
如图所示
请添加图片描述

我们在dispatch_async下断点,查看堆栈下的dispatch_async,就会来到汇编调用情况,其中我们可以看到libdispatch.dylib 调用了dispatch_async:,所以根据以前的经验,GCD的库就在libdispatch.dylib 里面.所以我们去源码中查看. 下载地址上面已给出。

libdispatch源码分析

当我翻开源码的时候,首先我发现,没法编译这份源码,其次源码中结构体、方法等的命名不能从字面理解,各种宏定义的嵌套错综复杂,所以看了半天有点读不下去了。但是,虽然不能像以前探索objc源码那样通过LLDB调试验证,但是我们可以从我们使用GCD流程下手,刨根问底,抱着探索求真的目的,顺着思路往下慢慢的找关键代码,然后进行分析其流程。

队列dispatch_queue_t

1.源码中全局去搜索找找dispatch_queue_t****

首先可以看到dispatch_queue_t本身只是dispatch_queue_s这个结构体指针

typedef struct dispatch_queue_s *dispatch_queue_t; 

2.继续查找dispatch_queue_s定义(搜索它dispatch_queue_s { )

struct dispatch_queue_s {
   
    DISPATCH_QUEUE_CLASS_HEADER(queue, void *__dq_opaque1);
    /* 32bit hole on LP64 */
} DISPATCH_ATOMIC64_ALIGN;

3. 继续查找DISPATCH_QUEUE_CLASS_HEADER ,发现是个宏如下

#define DISPATCH_QUEUE_CLASS_HEADER(x, __pointer_sized_field__) \
    _DISPATCH_QUEUE_CLASS_HEADER(x, __pointer_sized_field__); \
    /* LP64 global queue cacheline boundary */ \
    unsigned long dq_serialnum; \// queue的编号
    const char *dq_label; \   //标签
    DISPATCH_UNION_LE(uint32_t volatile dq_atomic_flags, \
        const uint16_t dq_width, \
        const uint16_t __dq_opaque2 \
    ); \
    dispatch_priority_t dq_priority; \//优先级
    union {
    \
        struct dispatch_queue_specific_head_s *dq_specific_head; \
        struct dispatch_source_refs_s *ds_refs; \
        struct dispatch_timer_source_refs_s *ds_timer_refs; \
        struct dispatch_mach_recv_refs_s *dm_recv_refs; \
        struct dispatch_channel_callbacks_s const *dch_callbacks; \
    }; \
    int volatile dq_sref_cnt

4. 宏里我们找到相关的方法_DISPATCH_QUEUE_CLASS_HEADER(x, pointer_sized_field); 继续展开搜索查看里面的内容如下

// 展开_DISPATCH_QUEUE_CLASS_HEADER

#define _DISPATCH_QUEUE_CLASS_HEADER(x, __pointer_sized_field__) \
    DISPATCH_OBJECT_HEADER(x); \
    DISPATCH_UNION_LE(uint64_t volatile dq_state, \
            dispatch_lock dq_state_lock, \
            uint32_t dq_state_bits \
    ); \

// 持续展开DISPATCH_OBJECT_HEADER

#define DISPATCH_OBJECT_HEADER(x) \
    struct dispatch_object_s _as_do[0]; \
    _DISPATCH_OBJECT_HEADER(x)
    
// 进一步查看 _DISPATCH_OBJECT_HEADER

#define _DISPATCH_OBJECT_HEADER(x) \
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值