欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS底层原理---GCD底层原理

程序员文章站 2022-04-27 11:44:16
简介...

1.简介

1.什么是GCD?

  • 全称是 Grand Central Dispatch
  • 纯 C 语言,提供了非常多强大的函数

2.GCD的优势

  • GCD 是苹果公司为多核的并行运算提出的解决方案
  • GCD 会自动利用更多的CPU内核(比如双核、四核)
  • GCD 会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
  • 程序员只需要告诉 GCD 想要执行什么任务,不需要编写任何线程管理代码

2.任务与队列

1.任务

  • 任务使用 block 封装
  • 任务的 block 没有参数也没有返回值
1.同步任务
  • 函数: dispatch_sync
  • 必须等待当前语句执行完毕,才会执行下一条语句
  • 不会开启线程
  • 在当前执行 block 的任务
2.异步任务
  • 异步 dispatch_async
  • 不用等待当前语句执行完毕,就可以执行下一条语句
  • 会开启线程执行 block 的任务
  • 异步是多线程的代名词

2.队列

1.串行队列
  • 任务顺序执行,one by one;
    iOS底层原理---GCD底层原理
2.并发队列
  • 任务随机执行,不需要等待,CPU调度
    iOS底层原理---GCD底层原理
3.主队列
  • 函数:dispatch_get_main_queue();
  • 特殊的串行队列
  • 专门用来在主线程上调度任务的队列
  • 不会开启线程
  • 如果当前主线程正在执行任务,那么无论主队列中当前被添加了什么任务,都不会被调度
4.全局队列
  • 函数:dispatch_get_global_queue(0,0);
  • 为了方便程序员使用,苹果提供了全局队列
  • 全局队列是一个并发队列
  • 在使用多线程开发时,如果对队列没有特殊需求,在执行异步任务时,可以直接使用全局队列
5.队列和任务搭配
  • 同步串行队列:不开启新线程,串行执行任务;
  • 同步并发队列:不开启新线程,串行执行任务;
  • 同步主队列:如果在主线程调用,造成死锁;如果在其他线程调用,不开启新线程,串行执行,在主线程串行执行任务;
  • 异步串行队列:开启新线程,串行执行任务;
  • 异步并发队列:开启新线程,并发执行任务;
  • 异步主队列:不开启新线程,在主线程串行执行任务
  • 死锁:
    iOS底层原理---GCD底层原理

2.GCD源码分析

首先搞了一份libdispatch的源码!

1.创建队列的代码

dispatch_queue_t queue = dispatch_queue_create("gcd_queue", DISPATCH_QUEUE_SERIAL);
//这里我们按住command ,Jump to Definition跳转到下面:
dispatch_queue_t
dispatch_queue_create(const char *_Nullable label,
	dispatch_queue_attr_t _Nullable attr);
//只能看到这里了
  • 我们只能去libdispatch源码中去看了!

  • 下面是我们源码搜索的过程:

  • 搜索dispatch_queue_createiOS底层原理---GCD底层原理

  • 搜索_dispatch_lane_create_with_target:

      //终于来到了核心代码!!!!
      //在下面的代码中根据参数dqa获取dqai,下面流程的判断都与dispatch_queue_attr_info_t dqai有关
      //那么说明dispatch_queue_attr_t dqa也是我们需要研究的对象
      //可以下略过此代码片,先去看一下dqa相关的东西,然后回来看下面代码,能使你更能清晰!!!!
      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);
      	
      	//优先级DISPATCH_QOS_USER_INITIATED 和 DISPATCH_QOS_BACKGROUND
      	dispatch_qos_t qos = dqai.dqai_qos;
      #if !HAVE_PTHREAD_WORKQUEUE_QOS
      	if (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 win
      		if (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 disallowed
      		if (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!
      			overcommit = dqai.dqai_concurrent ?
      					_dispatch_queue_attr_overcommit_disabled :
      					_dispatch_queue_attr_overcommit_enabled;
      		}
      	}
      	//***************************************************************
      	if (!tq) {
      		// 第一个参数 qos 为 4
      		//第二个参数 overcommit 并发为0,串行为1 
    
      		/*_dispatch_get_root_queue(dispatch_qos_t qos, bool overcommit)
      		{
      			if (unlikely(qos < DISPATCH_QOS_MIN || qos > DISPATCH_QOS_MAX)) {
      				DISPATCH_CLIENT_CRASH(qos, "Corrupted priority");
      			}
      			// 4-1= 3
      			// 返回值为 2*3+0/1 = 6/7
      			return &_dispatch_root_queues[2 * (qos - 1) + overcommit];
      		}
      		_dispatch_root_queues方法定义:从数组中取出下表为6/7的地址
      					
      		extern struct dispatch_queue_global_s _dispatch_root_queues[];
      		struct dispatch_queue_global_s _dispatch_root_queues[] = {
      		#define _DISPATCH_ROOT_QUEUE_IDX(n, flags) \
      				((flags & DISPATCH_PRIORITY_FLAG_OVERCOMMIT) ? \
      				DISPATCH_ROOT_QUEUE_IDX_##n##_QOS_OVERCOMMIT : \
      				DISPATCH_ROOT_QUEUE_IDX_##n##_QOS)
      		#define _DISPATCH_ROOT_QUEUE_ENTRY(n, flags, ...) \
      			[_DISPATCH_ROOT_QUEUE_IDX(n, flags)] = { \
      				DISPATCH_GLOBAL_OBJECT_HEADER(queue_global), \
      				.dq_state = DISPATCH_ROOT_QUEUE_STATE_INIT_VALUE, \
      				.do_ctxt = _dispatch_root_queue_ctxt(_DISPATCH_ROOT_QUEUE_IDX(n, flags)), \
      				.dq_atomic_flags = DQF_WIDTH(DISPATCH_QUEUE_WIDTH_POOL), \
      				.dq_priority = flags | ((flags & DISPATCH_PRIORITY_FLAG_FALLBACK) ? \
      						_dispatch_priority_make_fallback(DISPATCH_QOS_##n) : \
      						_dispatch_priority_make(DISPATCH_QOS_##n, 0)), \
      				__VA_ARGS__ \
      			}
      			_DISPATCH_ROOT_QUEUE_ENTRY(MAINTENANCE, 0,
      				.dq_label = "com.apple.root.maintenance-qos",
      				.dq_serialnum = 4,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(MAINTENANCE, DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
      				.dq_label = "com.apple.root.maintenance-qos.overcommit",
      				.dq_serialnum = 5,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(BACKGROUND, 0,
      				.dq_label = "com.apple.root.background-qos",
      				.dq_serialnum = 6,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(BACKGROUND, DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
      				.dq_label = "com.apple.root.background-qos.overcommit",
      				.dq_serialnum = 7,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(UTILITY, 0,
      				.dq_label = "com.apple.root.utility-qos",
      				.dq_serialnum = 8,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(UTILITY, DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
      				.dq_label = "com.apple.root.utility-qos.overcommit",
      				.dq_serialnum = 9,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(DEFAULT, DISPATCH_PRIORITY_FLAG_FALLBACK,
      				.dq_label = "com.apple.root.default-qos",
      				.dq_serialnum = 10,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(DEFAULT,
      					DISPATCH_PRIORITY_FLAG_FALLBACK | DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
      				.dq_label = "com.apple.root.default-qos.overcommit",
      				.dq_serialnum = 11,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(USER_INITIATED, 0,
      				.dq_label = "com.apple.root.user-initiated-qos",
      				.dq_serialnum = 12,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(USER_INITIATED, DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
      				.dq_label = "com.apple.root.user-initiated-qos.overcommit",
      				.dq_serialnum = 13,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(USER_INTERACTIVE, 0,
      				.dq_label = "com.apple.root.user-interactive-qos",
      				.dq_serialnum = 14,
      			),
      			_DISPATCH_ROOT_QUEUE_ENTRY(USER_INTERACTIVE, DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
      				.dq_label = "com.apple.root.user-interactive-qos.overcommit",
      				.dq_serialnum = 15,
      			),
      		};
      		返回值就是下面两个值:即是tq的值
      		_DISPATCH_ROOT_QUEUE_ENTRY(DEFAULT, DISPATCH_PRIORITY_FLAG_FALLBACK,
      				.dq_label = "com.apple.root.default-qos",
      				.dq_serialnum = 10,
      			),
      		_DISPATCH_ROOT_QUEUE_ENTRY(DEFAULT,
      					DISPATCH_PRIORITY_FLAG_FALLBACK | DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
      			.dq_label = "com.apple.root.default-qos.overcommit",
      			.dq_serialnum = 11,
      		),
      		*/
      		//tq模板式的创建
      		tq = _dispatch_get_root_queue(
      				qos == DISPATCH_QOS_UNSPECIFIED ? DISPATCH_QOS_DEFAULT : qos, 
      				overcommit == _dispatch_queue_attr_overcommit_enabled)->_as_dq; // 0 1
      		if (unlikely(!tq)) {
      			DISPATCH_CLIENT_CRASH(qos, "Invalid queue attribute");
      		}
      	}
      	if (legacy) {
      		// if any of these attributes is specified, use non legacy classes
      		if (dqai.dqai_inactive || dqai.dqai_autorelease_frequency) {
      			legacy = false;
      		}
      	}
      	const void *vtable;
      	dispatch_queue_flags_t dqf = legacy ? DQF_MUTABLE : 0;
      	// 通过dqai.dqai_concurrent 来区分并发和串行
      	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;
      		}
      	}	
    
      	// 开辟内存 - 生成响应的对象 queue
      	dispatch_lane_t dq = _dispatch_object_alloc(vtable,
      			sizeof(struct dispatch_lane_s));
      	/*
      	联合体:
      	typedef union {
      		struct _os_object_s *_os_obj;
      		struct dispatch_object_s *_do;
      		struct dispatch_queue_s *_dq;
      		struct dispatch_queue_attr_s *_dqa;
      		struct dispatch_group_s *_dg;
      		struct dispatch_source_s *_ds;
      		struct dispatch_mach_s *_dm;
      		struct dispatch_mach_msg_s *_dmsg;
      		struct dispatch_semaphore_s *_dsema;
      		struct dispatch_data_s *_ddata;
      		struct dispatch_io_s *_dchannel;
      	} dispatch_object_t DISPATCH_TRANSPARENT_UNION;
      	*/
    
      	//_dispatch_queue_init(dispatch_queue_class_t dqu, dispatch_queue_flags_t dqf,
      uint16_t width, uint64_t initial_state_bits)
      	// uint16_t width 传值: dqai.dqai_concurrent ?DISPATCH_QUEUE_WIDTH_MAX : 1 
      	//如果是并发队列 width传DISPATCH_QUEUE_WIDTH_MAX ,串行队列width传 1.
      	//几个宏定义:
      	//#define DISPATCH_QUEUE_WIDTH_FULL			0x1000ull
      	//#define DISPATCH_QUEUE_WIDTH_POOL (DISPATCH_QUEUE_WIDTH_FULL - 1) 这个是给queue_global使用
      	//#define DISPATCH_QUEUE_WIDTH_MAX  (DISPATCH_QUEUE_WIDTH_FULL - 2) 并发队列使用
      	// 构造方法:
      	_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;
      }
    
  • 搜索_dispatch_queue_attr_to_info (从上面知道这应该是个结构体类型的)与 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)
      {
      	//创建一个新的dqai结构体
      	dispatch_queue_attr_info_t dqai = { };
      	//判断dqa是否存在,不存在则直接返回,
      	//直接返回?????
      	//我们串行队列传进来的值是什么?
      	//#define DISPATCH_QUEUE_SERIAL NULL 
      	//传进来的是NULL,所以此处返回的是一个空值的结构体
      	if (!dqa) return dqai;
      	//如果不是串行队列,那么进行下面的dqai结构体的赋值
      #if DISPATCH_VARIANT_STATIC
      	if (dqa == &_dispatch_queue_attr_concurrent) {
      		dqai.dqai_concurrent = true;
      		return dqai;
      	}
      #endif
    
      	if (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);
    
      	// 位域
      	// 0000 000000000 00000000000 0000 000  1
      	//dqa结构体位域赋值
      	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 = -(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;
      }
      //看完这些,我们回到上面的_dispatch_lane_create_with_target代码去接着分析!!!!
    

2.主队列与全局队列的创建

1.dispatch_get_global_queue(0, 0)
dispatch_queue_global_t
dispatch_get_global_queue(long identifier, unsigned long flags);

typedef struct dispatch_queue_global_s *dispatch_queue_global_t;
struct dispatch_queue_global_s _dispatch_root_queues[] = {
#define _DISPATCH_ROOT_QUEUE_IDX(n, flags) \
	((flags & DISPATCH_PRIORITY_FLAG_OVERCOMMIT) ? \
	DISPATCH_ROOT_QUEUE_IDX_##n##_QOS_OVERCOMMIT : \
	DISPATCH_ROOT_QUEUE_IDX_##n##_QOS)
#define _DISPATCH_ROOT_QUEUE_ENTRY(n, flags, ...) \
	[_DISPATCH_ROOT_QUEUE_IDX(n, flags)] = { \
		DISPATCH_GLOBAL_OBJECT_HEADER(queue_global), \
		.dq_state = DISPATCH_ROOT_QUEUE_STATE_INIT_VALUE, \
		.do_ctxt = _dispatch_root_queue_ctxt(_DISPATCH_ROOT_QUEUE_IDX(n, flags)), \
		.dq_atomic_flags = DQF_WIDTH(DISPATCH_QUEUE_WIDTH_POOL), \
		.dq_priority = flags | ((flags & DISPATCH_PRIORITY_FLAG_FALLBACK) ? \
				_dispatch_priority_make_fallback(DISPATCH_QOS_##n) : \
				_dispatch_priority_make(DISPATCH_QOS_##n, 0)), \
		__VA_ARGS__ \
	}
	_DISPATCH_ROOT_QUEUE_ENTRY(MAINTENANCE, 0,
		.dq_label = "com.apple.root.maintenance-qos",
		.dq_serialnum = 4,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(MAINTENANCE, DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
		.dq_label = "com.apple.root.maintenance-qos.overcommit",
		.dq_serialnum = 5,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(BACKGROUND, 0,
		.dq_label = "com.apple.root.background-qos",
		.dq_serialnum = 6,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(BACKGROUND, DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
		.dq_label = "com.apple.root.background-qos.overcommit",
		.dq_serialnum = 7,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(UTILITY, 0,
		.dq_label = "com.apple.root.utility-qos",
		.dq_serialnum = 8,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(UTILITY, DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
		.dq_label = "com.apple.root.utility-qos.overcommit",
		.dq_serialnum = 9,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(DEFAULT, DISPATCH_PRIORITY_FLAG_FALLBACK,
		.dq_label = "com.apple.root.default-qos",
		.dq_serialnum = 10,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(DEFAULT,
		DISPATCH_PRIORITY_FLAG_FALLBACK | DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
		.dq_label = "com.apple.root.default-qos.overcommit",
		.dq_serialnum = 11,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(USER_INITIATED, 0,
		.dq_label = "com.apple.root.user-initiated-qos",
		.dq_serialnum = 12,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(USER_INITIATED, DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
		.dq_label = "com.apple.root.user-initiated-qos.overcommit",
		.dq_serialnum = 13,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(USER_INTERACTIVE, 0,
		.dq_label = "com.apple.root.user-interactive-qos",
		.dq_serialnum = 14,
	),
	_DISPATCH_ROOT_QUEUE_ENTRY(USER_INTERACTIVE, DISPATCH_PRIORITY_FLAG_OVERCOMMIT,
		.dq_label = "com.apple.root.user-interactive-qos.overcommit",
		.dq_serialnum = 15,
	),
};
//global_queue也是使用模板式创建
2.dispatch_get_main_queue()
dispatch_queue_main_t
dispatch_get_main_queue(void)
{
	return DISPATCH_GLOBAL_OBJECT(dispatch_queue_main_t, _dispatch_main_q);
}
typedef struct dispatch_queue_static_s *dispatch_queue_main_t;
struct dispatch_queue_static_s _dispatch_main_q = {
DISPATCH_GLOBAL_OBJECT_HEADER(queue_main),
#if !DISPATCH_USE_RESOLVERS
	.do_targetq = _dispatch_get_default_queue(true),
#endif
	.dq_state = DISPATCH_QUEUE_STATE_INIT_VALUE(1) |
			DISPATCH_QUEUE_ROLE_BASE_ANON,
	.dq_label = "com.apple.main-thread",
	.dq_atomic_flags = DQF_THREAD_BOUND | DQF_WIDTH(1),
	.dq_serialnum = 1, //从这里我们也能看出来,主队列是串行队列
};
//struct dispatch_queue_static_s 主队列使用一个静态的来创建

3._dispatch_root_queues[]的创建.

  • 这个创建过程在我们加载动态库libdispatch_dyld时创建.

      //创建
      void _dispatch_introspection_init(void)
      {
      	_dispatch_introspection.debug_queue_inversions =
      			_dispatch_getenv_bool("LIBDISPATCH_DEBUG_QUEUE_INVERSIONS", false);
    
      	// Hack to determine queue TSD offset from start of pthread structure
      	uintptr_t thread = _dispatch_thread_self();
      	thread_identifier_info_data_t tiid;
      	mach_msg_type_number_t cnt = THREAD_IDENTIFIER_INFO_COUNT;
      	kern_return_t kr = thread_info(pthread_mach_thread_np((void*)thread),
      	THREAD_IDENTIFIER_INFO, (thread_info_t)&tiid, &cnt);
      	if (!dispatch_assume_zero(kr)) {
      		_dispatch_introspection.thread_queue_offset =
      				(void*)(uintptr_t)tiid.dispatch_qaddr - (void*)thread;
      	}
      	_dispatch_thread_key_create(&dispatch_introspection_key, _dispatch_introspection_thread_remove);
      	_dispatch_introspection_thread_add(); // add main thread
      	//循环创建_dispatch_root_queues[i];
      	for (size_t i = 0; i < DISPATCH_ROOT_QUEUE_COUNT; i++) {
      		_dispatch_trace_queue_create(&_dispatch_root_queues[i]);
      	}
      #if DISPATCH_USE_MGR_THREAD && DISPATCH_USE_PTHREAD_ROOT_QUEUES
      	_dispatch_trace_queue_create(_dispatch_mgr_q.do_targetq);
      #endif
      	_dispatch_trace_queue_create(&_dispatch_main_q);//主队列创建
      	_dispatch_trace_queue_create(&_dispatch_mgr_q);
      }
    
      //创建方法
      static inline dispatch_queue_class_t
      _dispatch_trace_queue_create(dispatch_queue_class_t dqu)
      {
      	_dispatch_only_if_ktrace_enabled({
      		uint64_t dq_label[4] = {0}; // So that we get the right null termination
      		dispatch_queue_t dq = dqu._dq;
      		strncpy((char *)dq_label, (char *)dq->dq_label ?: "", sizeof(dq_label));
    
      		_dispatch_ktrace2(DISPATCH_QOS_TRACE_queue_creation_start,
      				dq->dq_serialnum,
      				_dispatch_priority_to_pp_prefer_fallback(dq->dq_priority));
    
      		_dispatch_ktrace4(DISPATCH_QOS_TRACE_queue_creation_end,
      				dq_label[0], dq_label[1], dq_label[2], dq_label[3]);
      	});
    
      	return _dispatch_introspection_queue_create(dqu);
      }
    
  • 主队列是在初始化的时候,单独创建的,并未使用_dispatch_root_queues[]模板创建!其他均是通过_dispatch_root_queues[]创建.

至此,GCD的队列创建流程就探索完了,写的很乱,仔细的去分析哦!下一篇会去看和函数相关的知识,敬请期待…

本文地址:https://blog.csdn.net/weixin_39950838/article/details/106528252

相关标签: iOS开发