1、创建队列的时候采用 dispatch_queue_create、底层内部源码为

2、调用源码

dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)
{return _dispatch_lane_create_with_target(label, attr, DISPATCH_TARGET_QUEUE_DEFAULT, true);
}

3、_dispatch_lane_create_with_target实现过程为

    1. 优先级判断
    2. 异常处理
    3. 串并行队列判断、串为_dispatch_queue_attr_overcommit_enabled、并发为_dispatch_queue_attr_overcommit_disabled
    4. 初始化queue
    5. 开辟内存-生成响应的对象queue
    6. 构造方法
    7. 标签赋值
    8. 优先级处理
DISPATCH_NOINLINE
static dispatch_queue_t
_dispatch_lane_create_with_target(const char *label, dispatch_queue_attr_t dqa,dispatch_queue_t tq, bool legacy)
{dispatch_queue_attr_info_t dqai = _dispatch_queue_attr_to_info(dqa);//// Step 1: Normalize arguments (qos, overcommit, tq)////优先级判断dispatch_qos_t qos = dqai.dqai_qos;
#if !HAVE_PTHREAD_WORKQUEUE_QOSif (qos == DISPATCH_QOS_USER_INTERACTIVE) {dqai.dqai_qos = qos = DISPATCH_QOS_USER_INITIATED;}if (qos == DISPATCH_QOS_MAINTENANCE) {dqai.dqai_qos = qos = DISPATCH_QOS_BACKGROUND;}
#endif // !HAVE_PTHREAD_WORKQUEUE_QOS//异常处理_dispatch_queue_attr_overcommit_t overcommit = dqai.dqai_overcommit;if (overcommit != _dispatch_queue_attr_overcommit_unspecified && tq) {if (tq->do_targetq) {DISPATCH_CLIENT_CRASH(tq, "Cannot specify both overcommit and ""a non-global target queue");}}if (tq && dx_type(tq) == DISPATCH_QUEUE_GLOBAL_ROOT_TYPE) {// Handle discrepancies between attr and target queue, attributes winif (overcommit == _dispatch_queue_attr_overcommit_unspecified) {if (tq->dq_priority & DISPATCH_PRIORITY_FLAG_OVERCOMMIT) {overcommit = _dispatch_queue_attr_overcommit_enabled;} else {overcommit = _dispatch_queue_attr_overcommit_disabled;}}if (qos == DISPATCH_QOS_UNSPECIFIED) {qos = _dispatch_priority_qos(tq->dq_priority);}tq = NULL;} else if (tq && !tq->do_targetq) {// target is a pthread or runloop root queue, setting QoS or overcommit// is disallowedif (overcommit != _dispatch_queue_attr_overcommit_unspecified) {DISPATCH_CLIENT_CRASH(tq, "Cannot specify an overcommit attribute ""and use this kind of target queue");}} else {if (overcommit == _dispatch_queue_attr_overcommit_unspecified) {// Serial queues default to overcommit! 并发disabled 串行enabledovercommit = dqai.dqai_concurrent ?_dispatch_queue_attr_overcommit_disabled :_dispatch_queue_attr_overcommit_enabled;}}if (!tq) {tq = _dispatch_get_root_queue(qos == DISPATCH_QOS_UNSPECIFIED ? DISPATCH_QOS_DEFAULT : qos,//DISPATCH_QOS_DEFAULT = 4overcommit == _dispatch_queue_attr_overcommit_enabled)->_as_dq;//串1 并0if (unlikely(!tq)) {DISPATCH_CLIENT_CRASH(qos, "Invalid queue attribute");}}//// Step 2: Initialize the queue// 初始化 queueif (legacy) {// if any of these attributes is specified, use non legacy classesif (dqai.dqai_inactive || dqai.dqai_autorelease_frequency) {legacy = false;}}const void *vtable;dispatch_queue_flags_t dqf = legacy ? DQF_MUTABLE : 0;if (dqai.dqai_concurrent) {vtable = DISPATCH_VTABLE(queue_concurrent);} else {vtable = DISPATCH_VTABLE(queue_serial);}switch (dqai.dqai_autorelease_frequency) {case DISPATCH_AUTORELEASE_FREQUENCY_NEVER:dqf |= DQF_AUTORELEASE_NEVER;break;case DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM:dqf |= DQF_AUTORELEASE_ALWAYS;break;}if (label) {const char *tmp = _dispatch_strdup_if_mutable(label);if (tmp != label) {dqf |= DQF_LABEL_NEEDS_FREE;label = tmp;}}//开辟内存-生成响应的对象 queuedispatch_lane_t dq = _dispatch_object_alloc(vtable,sizeof(struct dispatch_lane_s));//构造方法_dispatch_queue_init(dq, dqf, dqai.dqai_concurrent ?DISPATCH_QUEUE_WIDTH_MAX : 1, DISPATCH_QUEUE_ROLE_INNER |(dqai.dqai_inactive ? DISPATCH_QUEUE_INACTIVE : 0));//标签dq->dq_label = label;//优先级dq->dq_priority = _dispatch_priority_make((dispatch_qos_t)dqai.dqai_qos,dqai.dqai_relpri);if (overcommit == _dispatch_queue_attr_overcommit_enabled) {dq->dq_priority |= DISPATCH_PRIORITY_FLAG_OVERCOMMIT;}if (!dqai.dqai_inactive) {_dispatch_queue_priority_inherit_from_target(dq, tq);_dispatch_lane_inherit_wlh_from_target(dq, tq);}_dispatch_retain(tq);dq->do_targetq = tq;_dispatch_object_debug(dq, "%s", __func__);return _dispatch_trace_queue_create(dq)._dq;
}

4、其中 _dispatch_queue_attr_to_info(dqa);调用时dispatch_queue_attr_info_t 结构体为位域、那么该函数的作用为赋值。

//位域 赋值
typedef struct dispatch_queue_attr_info_s {dispatch_qos_t dqai_qos : 8;int      dqai_relpri : 8;uint16_t dqai_overcommit:2;uint16_t dqai_autorelease_frequency:2;uint16_t dqai_concurrent:1;uint16_t dqai_inactive:1;
} dispatch_queue_attr_info_t;
  • 赋值操作
dispatch_queue_attr_info_t
_dispatch_queue_attr_to_info(dispatch_queue_attr_t dqa)
{dispatch_queue_attr_info_t dqai = { };//当前空的结构体指针、则直接返回if (!dqa) return dqai;
#if DISPATCH_VARIANT_STATICif (dqa == &_dispatch_queue_attr_concurrent) {dqai.dqai_concurrent = true;return dqai;}
#endifif (dqa < _dispatch_queue_attrs ||dqa >= &_dispatch_queue_attrs[DISPATCH_QUEUE_ATTR_COUNT]) {DISPATCH_CLIENT_CRASH(dqa->do_vtable, "Invalid queue attribute");}size_t idx = (size_t)(dqa - _dispatch_queue_attrs);dqai.dqai_inactive = (idx % DISPATCH_QUEUE_ATTR_INACTIVE_COUNT);idx /= DISPATCH_QUEUE_ATTR_INACTIVE_COUNT;//并发队列dqai.dqai_concurrent = !(idx % DISPATCH_QUEUE_ATTR_CONCURRENCY_COUNT);idx /= DISPATCH_QUEUE_ATTR_CONCURRENCY_COUNT;dqai.dqai_relpri = -(int)(idx % DISPATCH_QUEUE_ATTR_PRIO_COUNT);idx /= DISPATCH_QUEUE_ATTR_PRIO_COUNT;dqai.dqai_qos = idx % DISPATCH_QUEUE_ATTR_QOS_COUNT;idx /= DISPATCH_QUEUE_ATTR_QOS_COUNT;dqai.dqai_autorelease_frequency =idx % DISPATCH_QUEUE_ATTR_AUTORELEASE_FREQUENCY_COUNT;idx /= DISPATCH_QUEUE_ATTR_AUTORELEASE_FREQUENCY_COUNT;dqai.dqai_overcommit = idx % DISPATCH_QUEUE_ATTR_OVERCOMMIT_COUNT;idx /= DISPATCH_QUEUE_ATTR_OVERCOMMIT_COUNT;return dqai;
}

5、_dispatch_queue_init方法

// Note to later developers: ensure that any initialization changes are
// made for statically allocated queues (i.e. _dispatch_main_q).
static inline dispatch_queue_class_t
_dispatch_queue_init(dispatch_queue_class_t dqu, dispatch_queue_flags_t dqf,uint16_t width, uint64_t initial_state_bits)
{uint64_t dq_state = DISPATCH_QUEUE_STATE_INIT_VALUE(width);dispatch_queue_t dq = dqu._dq;dispatch_assert((initial_state_bits & ~(DISPATCH_QUEUE_ROLE_MASK |DISPATCH_QUEUE_INACTIVE)) == 0);if (initial_state_bits & DISPATCH_QUEUE_INACTIVE) {dq->do_ref_cnt += 2; // rdar://8181908 see _dispatch_lane_resumeif (dx_metatype(dq) == _DISPATCH_SOURCE_TYPE) {dq->do_ref_cnt++; // released when DSF_DELETED is set}}dq_state |= initial_state_bits;dq->do_next = DISPATCH_OBJECT_LISTLESS;dqf |= DQF_WIDTH(width);os_atomic_store2o(dq, dq_atomic_flags, dqf, relaxed);dq->dq_state = dq_state;dq->dq_serialnum =os_atomic_inc_orig(&_dispatch_queue_serial_numbers, relaxed);return dqu;
}

dispatch_queue_create创建源码分析相关推荐

  1. spring boot实战(第九篇)Application创建源码分析

    前言 通过前面的文章了解到在spring boot的启动时,利用的是编写的Application类,使用了注解@SpringBootApplication,本篇将阐述该Bean的加载过程. [html ...

  2. Netty-服务端channl的创建(源码分析)

    文章目录 服务端启动的流程 创建服务端channel 初始化服务端channel 注册selector 端口绑定 服务端启动的流程 创建服务端channel AbstractBootstrap.jav ...

  3. linux 2.6线程创建源码分析

    2019独角兽企业重金招聘Python工程师标准>>> 上章讲到线程,现在对线程创建的代码流程分析下.来一步一步揭开她神秘的面纱 linux内核创建线程函数 kernel_threa ...

  4. 【Java】NIO中Selector的select方法源码分析

    该篇博客的有些内容和在之前介绍过了,在这里再次涉及到的就不详细说了,如果有不理解请看[Java]NIO中Channel的注册源码分析, [Java]NIO中Selector的创建源码分析 Select ...

  5. Android 9(P)之init进程启动源码分析指南之一

         Android 9 之init进程启动源码分析指南之一 Android 9 (P) 系统启动及进程创建源码分析目录: Android 9 (P)之init进程启动源码分析指南之一 Andro ...

  6. Android 9 (P)之init进程启动源码分析指南之三

          Android 9 (P)之init进程启动源码分析指南之三 Android 9 (P)系统启动及进程创建源码分析目录: Android 9 (P)之init进程启动源码分析指南之一 An ...

  7. Android 9 (P) Zygote进程启动源码分析指南二

         Android 9 Zygote进程启动源码分析指南二 Android 9 (P) 系统启动及进程创建源码分析目录: Android 9 (P)之init进程启动源码分析指南之一 Andro ...

  8. Django源码分析1:创建项目和应用分析

    django命令行源码分析 本文环境python3.5.2,django1.10.x系列 当命令行输入时django-admin时 (venv) ACA80166:dbManger wuzi$ dja ...

  9. Openstack Nova 源码分析 — 使用 VCDriver 创建 VMware Instance

    目录 目录 前言 流程图 nova-compute vCenter 前言 在上一篇 Openstack Nova 源码分析 - Create instances (nova-conductor阶段) ...

  10. netty 5 alph1源码分析(服务端创建过程)

    研究了netty的服务端创建过程.至于netty的优势,可以参照网络其他文章.<Netty系列之Netty 服务端创建>是 李林锋撰写的netty源码分析的一篇好文,绝对是技术干货.但抛开 ...

最新文章

  1. redis3.2安装过程分享
  2. Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍
  3. linux编辑文本文件aa的命令,linux入门必须掌握的命令--文本文件编辑
  4. 为什么Spring Boot项目引入依赖的时候可以不指定依赖的版本号
  5. 在Firefox 58中,WebAssembly组件性能提升了10倍
  6. CIFAR和SVHN在各CNN论文中的结果
  7. Shell编程入门(第二版)(中)
  8. C++之静态成员变量和静态成员函数
  9. 免费送书的网站-每人限一本
  10. 201计算机基础知识,201年计算机应用基础备考练习题及答案
  11. [转载] 05 Numpy排序搜索计数及集合操作
  12. proFTPd的使用配置
  13. 数据库基本----SQL语句大全(转载)
  14. vMix(视频混合器软件)v22.0.0.48免费版
  15. 微博话题墙 html,Js仿微博插入话题功能
  16. PPT2010无法从所选的文件中插入视频
  17. python学习记录 day1
  18. 津巴布韦元以美元背书缓解货币贬值
  19. 三个步骤 让你学会看懂考研数学课本
  20. H5实现APP下载功能

热门文章

  1. 08-3 Kubernetes 调度器 - 污点
  2. 360路由器故障显示DNS服务器,360安全路由器dns异常解决方法
  3. 天猫精灵 python_天猫精灵控制esp8266点led灯
  4. 海尔集团CEO张瑞敏演讲《人不成熟的几大特征》
  5. Java使用BufferedImage裁剪图片
  6. 古风一棵桃花树简笔画_唯美意境桃花古风句子
  7. C语言位运算-实现Photoshop反向功能
  8. 人在广州,力撑陈 Sir
  9. 【牛客网】C/C++牛客网专项刷题(04)
  10. unity tags的坑