-
常见数据结构
-
dispatch_object_t
GCD
一切类的基类
从源码能够看出dispatch_object_t
是一个联合体(并且是一个源码本钱通明联合体线程),便是dispatch_object_t
可所以结构体中的任意一种类型,巨细为这些数据类型中最大的数据类型的巨细 -
_os_object_s
-
dispatch_object_s
-
dispatch_continuation_s
dispatch_continuation_s
结构体首要封装block
和function
,dispatch_async
中的bloc线程撕裂者k
究竟都会封装成这个数据类型
-
dispatch_group_s
-
dispatch源码本钱_queue_s
-
-
创立部队源码剖析
-
dispatch_queue_create
源码第一步下一个符号断点
发现源码在libdisp数据结构难学吗atch.dylib
库中,然后下载libdispatch.dylib
源码查找dispatch_queue_create
能够找到其实冲仓库信息中也能够知道接下来调用了_dispatch_lane_create_with_target
函数来完毕创立 -
_dispatch_lane_create_with_target
源码- 标准化参数
- 设置方针部队
调用_dispatch_get_root_queue
办法获取方针部队
假定是串行部队,则运用_dispatch_get_root_queue(0, true)
函数获取方针部队,获取到的方针部队是_dispatch_root_queues[DISPATCH_ROOT_QUEUE_IDX_DEFAULT_OVERCOM线程池的创立办法有几种MIT_PRIORITY]
。
假定是并发部队,则运用_dispatch数据结构教程第5版李春葆答案_get_root_queue(线程和进程的差异是什么0, false)
函数获取方针部队,获取到的方针部队是_dispatch_root数据结构_queues[DISPATCH_ROOT_QUEUE_IDX_DEF源码编辑器编程猫下载AULT_PRIORITY]
。 - 开荒空间创立部队
_dispatch_obj源码网站ect_alloc
开荒空间创立部队 - 初始化部队
_dispatch_queue_init
初源码始化部队,这儿依据第一步标准后的参数据结构c语言版严蔚敏数判别设置最大并发数,D源码编辑器手机版下载ISPATCH_QUEUE_WIDTH_MAX
从这儿也能够知道最大的并发数是4094
设置部队标识符等 - 赋值方针部队
将上述设置的方针部队赋值
-
部队和线程之间的联络图
-
-
函数源码剖析
-
异步函数剖析
-
_dispatch_continuation_init
使命包装函数首要是copy任线程和进程的差异是什么务,赋值func、ctxt等参数
经过_d线程池面试题ispatch_continuation_init_f
函数赋值func、ctxt等参数
-
_d数据结构知识点总结ispatch_continuation线程池面试题_async
并发处理函数
大局查找dx_push
发现是数据结构题库及答案个宏#define dx_push(x, y数据结构与算法, z) dx_源码之家vtable(x)->dq_push(x, y, z)
,发现源码仍是调用了dq_push
办法持续大局查找d数据结构c语言版q_push
发现dq_push
办法有很多个不过每个上面有类型不难猜测异步函数应该对应数据结构c语言版第二版课后答案的是queue_concurrent
下的办法对应的办法是_dispatch_lane_concurrent_push
这儿能够经过下符号断点来验证首要数据结构严蔚敏现在异数据结构期末考试题及答案步函数钱下个断点然后再往下走发现断在了_dispatch_lane_concurr数据结构严蔚敏ent_push
的办法仓库上所以也验证了上述猜测,持续往下跟,大局查找_dispatch_lane_concurrent_线程池的创立办法有几种push
使命实施即出队所以一般并行部队中的异步使命的话都是空的所以假定不增加栅门函数则一般会实施_dispatch_continuation_redirect_push
办法这儿也能够线程池面试题经过增加符号断点来验证发现确实_di源码集市spatch_lane_concurrent_push
办法实施完毕之后直接进入到_dispatch_continuation_redirect_push
办法然后就实施了使命持续大局数据结构题库及答案查找_d线程是什么意思ispatch_continuation_redirect_push
办法此刻的dq_push
对应的就不是_dispatch_lane_concurrent_push
办法了由于对应的部队类型变成了跟队线程撕裂者伍,所以线程池参数此刻应该对应的是_dispatch_r源码编辑器手机版下载oot_queue_push
办法相同的也能够依据上述的进程下一个符号断点来验证线程安全,持续大局查找_dispatch_root_queu源码编辑器e_push
办法下个_dispatch_ro线程的几种状况ot_queue_pus数据结构期末考试题及答案h_override
符号断数据结构难学吗点鄙人一源码编辑器手机版下载个_dispatch_root_qu数据结构与算法eue_push_inline
符号断点发现会走到_dispatch_root_queue_pu数据结构c语言版严蔚敏sh_override数据结构期末考试题及答案
办法中然后里面又持续调用了_dispatch_root_queue_push_数据结构与算法inline
办法持续查找_dispatch_roo线程池的创立办法有几种t_queue_poke
办法大局查找_dispatch_root_queue_poke_slow
办法到这儿异步函数创立线程的流程就现已结线程和进程的差异是什么束如下图可是此刻仅仅是创立了线程,但线程安全是使命还没有实施此刻再看上方的_dispatch_root_queues_init
办法点进去发现发现是数据结构严蔚敏dispatch_onc数据结构c语言版严蔚敏e_f
办法调用传入的fun源码编辑器编程猫下载c
是_dispatch_root_queues_init_once
,持续进到数据结构c语言版第二版课后答案_dispatch_worker_thread2
(线程的实施是体系底层去启航的,这儿只源码编辑器手机版下载需求绑定线程,体系会去触发线程)办法查看源码_dispatch_root_queue_drain
办法源码究竟发现在这儿调用了使命办法,剖析之前完全能够打数据结构题库及答案断点然后打印仓库调用状况然后再去源码中找对应代码源码网站,仓库调用状况如下:发现仓库的调用状况就和上述剖析的流程共数据结构c语言版严蔚敏同,
总流程图如下:线程池面试题
-
-
同步函数剖析
首要看
dispatch_sync
源码持续看_dispatch_sync_f
源码发现同步函数据结构c语言版第二版课后答案数的当地便是经过栅门函数来完毕的(栅门函数源码如下源码之家)
-
-
栅门函数源码剖析
- 同步栅门函数有必要自己的block使命实施完毕,下面的使命block才会实施,这就标明同步堵塞的是当时的线程
- 异步栅门函数不需求等自己的使命block实施,下面的代码会接着实施,这就标明异步堵塞的是部队(queue)。
留神:栅门函数只能用在并发自定义部队数据结构题库及答案中,大局并发部队,假定堵塞了其他体系使命,会形成其他使命,串行部队运用栅门函数等于没用
dispatch_bar线程的几种状况rier_sync
源码如下源码之家:
同步栅门函数源码流程: -
死锁源码剖析
上述栅门函数源码编辑器手机版下载剖析得知死锁在
_dispatch_sync_f_slow
办法中处理的首要将当时使命增加到部队中然后实施__DISPATCH_WAIT_FOR_QUEUE__
办法再看_dq_state_drain_locked_by
办法源码判别dq是否为正在等候的部队源码编辑器手机版下载,然后给出一个状况state,然后将dq的状况和数据结构严蔚敏当时使命依托的部队进行匹配,匹配成功则抛出失常 -
单列源码剖析
大局查找
dispatch_once
查看源码一同发现_dispatch_Block_i线程的几种状况nvoke
便是一数据结构c语言版严蔚敏个宏#defi线程撕裂者ne _dispatch_Block_invoke(bb) (线程池的创立办法有几种(dispatch_function_t数据结构期末考试题及答案)((struct Block_layout *)bb)->invoke)
便是invoke办法
单例底层完毕流程图 -
信号量
控制最大并发量(一般运用不多)中心函数如下:
-
dispatch_semaphore_create
创立信号量,指定最大并发数 -
dispatch_semaphore_signal
发送信号 -
dispatch_semaphore_wait
等源码编辑器手机版下载候信号
代码示例如下线程同步:
- (void)viewDidLoad { [super viewDidLoad]; dispatch_queue_t queue = dispatch_get_global_queue(数据结构题库及答案0, 0); dispatch_semaphore_t se线程和进程的差异是什么m = dispatch_semaphore_create(2); //使命1 dispatch_async(queue, ^{ dispa线程tch_semaphore_wait(se数据结构期末考试题及答案m, DISPATCH_TIME_FOREVER); NSLog(@"实施使命1"); sleep(1); NSLog(@"使命1完毕"); dispatch_semaphore_signal(sem); }); //使命2 dispatch_async数据结构知识点总结(queue, ^{ dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); NSLog(@"实施使命2"); sleep(1); NSLog(@"使命2完毕"); dispatch_sem线程撕裂者aphore_signal(se数据结构c语言版m); }线程是什么意思); //使命3 dispatch_async(queue, ^{ dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); NSLog(@"实施使命3"); sleep(1); NSLog(@"使命3完毕"); d源码编辑器手机版下载ispatch_semaphore_signal(sem); }); }
打印效果源码本钱如下:能够发现由于控制最大的并发量是2所以能一同实施的使命有两个,此刻使命一和使命2是一同实施的,使命三是比及前两个使命实施线程的几种状况完毕之后再实施的
源码剖析:-
dispatch_semap数据结构严蔚敏hore_create
-
dispatch_semaphore_wait
首要是对并发量进行–操作,假定当时的并发量现已小于0了阐明当时现已达到了最大并发量,所以使命进行无限等候源码编辑器状况(堵塞线程)源码如下
os_atomic_dec2o
是个宏,由于里面是一个一个宏嵌套,所以这儿一个一个剖析后如下;os源码分享网_atomic_dec2o(dsema, dsema_value, a源码cquire); os_atomic_sub2o(ds源码集市ema, dsema_value, 1, acquire) os_atomic_线程是什么意思sub(&(dsema)->dsema_value, (1), acquire) _os_atomic_c11_op(&(dsema)->dsema_value, (1), a源码集市cquire, sub, -) atom数据结构题库及答案ic_fetch_sub_explicit(&(dsema)->dsema_value, 1) 等价于&(dsema)->dsema_value = &(dsema)-&g源码网站t;dsema_value -1
-
dispatch_semaphore_signal
-
-
调度组
调度组首要的效果便是监听某些使命实施状况,比如现在需求改写UI可是需求两个央求完毕之后再改写UI,此刻就能够运用调度组,能够等候两个异步使命完毕之后收到完毕奉告后再改写UI
中心函数:-
dispatch_group_create
创立组 -
dispatch_group_async
进组使命 -
dispatch_group_not线程池面试题ify
等候使命实施完毕奉告 -
dispatch_group_wait
暂数据结构c语言版停当时线程(堵塞当时线程),等源码编辑器候指定的 group 中的使命实施完毕后,才会往下持续实施 -
dispatch_gr源码之家oup_enter
标志着一个数据结构与算法使命追加到 group,实施一线程是什么意思次,相当于group 中未实施完毕使命数+1 -
dispatch_group_leave
标志着一个使命离开了 gr源码分享网oup,实施一次,相当于 group 中未实施完毕使命数-1。
留神:
dispatch_group_leave
和dispatch_group_enter
需求成对出现
运用示例:- 正常状况示例源码年代
- 运用
dispatch_group_wait
dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_glob线程al_queu线程池的创立办法有几种e(0, 0);线程池参数 dispatch_group_enter(group); dispatch_asy源码网站nc(queue, ^{ sleep(1); NSLog(@"使命1实施完毕"); d线程同步ispatch_group_leave(group); }); dispatch_group_enter(group); dispatch_async(queue, ^{ N线程同步SLog(@"使命2实施线程池面试题完毕"); dispatch_group_leave(group); }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ sleep(3); NSLog(@"使命3实施完毕"); }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"使命1、2实施完毕"); }); NSLog(@"使命6实施完毕(主线程)");
- 特别状况1(将奉告放在最前面)
dispatch_group_t g线程是什么意思roup = dispatch_group_create(); dispatch_q数据结构教程第5版李春葆答案ueue_t queue = dispatch_线程同步get_global_queue(0, 0); dispatch_group_notify(group, dis数据结构与算法patch_get_main_queue(), ^{ NSLog源码超市(@"使命1、2实施完毕"); }); dispatch_group_enter(group); dispatch_async(queue, ^{ sleep(1); NSLog(@"使命1实施完毕"); dispatch_group_leave(group); }); disp线程at线程ch_group_enter(group); dispatch_async(queue, ^{ NSLog(@"使命2实施完毕"); dispatch_group_线程同步leave(group); }); dispatch_async源码编辑器手机版下载(dispatch_get_global_queue(0, 0), ^{ sleep(源码网站3); NSLog(@"使命3实施完毕"); }); NSLog(@"使命6实数据结构与算法行完毕(主线程)");数据结构严蔚敏
- 特别状况2(多一个)
dispatch_group_enter
dispatch源码之家_group_t group = dispatch线程池参数_group_c线程reate(); dispatch_queue_t queue = dispatch_get_g数据结构题库及答案lobal_queue(源码年代0, 0); di数据结构spatch_gr线程撕裂者oup_enter(group); dis数据结构c语言版第二版课后答案patch_asy数据结构难学吗nc(queue, ^{ sleep(1); NSLog(@"使命1实施完毕"); dispatch_group_leave(group); }); dispatch_group_enter(group); dispatch_async(queue, ^{ NSLog(@"使命2实施完毕"); dispatch_group_leave(group); }); dispatch_group_enter(group); dispatch_async(dispatch_get_global_queue(0, 0), ^{ sleep(3); NSLog(@"使命3实施完毕"); }); dispatch_group_notify(group, dispatch_源码编辑器get_main_queue(), ^{ NSLog(@"使命1、2实施完毕"); }); NSLog(@"使命6实施完毕(主线程)");
- 特别状况2(多一个)
dispatch_group_leave
直接会溃散,所以说dispatch_group_leave
和dispatch_group_ente源码网站r
一定要成数据结构教程第5版李春葆答案对出现
源码探究:
-
-
Dispatch Source源码网站
在任⼀线程上调⽤它的的⼀个函数
dispatch_source_merge_data
后,会执⾏Dispatch Source
事前定义好的句柄(能够把句柄简略理解为⼀个 block )这个进程叫Custom event,⽤户作业。是dispatch source
⽀持处理的⼀种作业
句柄是⼀种指向指针的指针 它指向的便是⼀个类或许结构,它和体系有很密切的联络 HINSTANCE(实线程是什么意思例句柄),HBITMAP(位图句数据结构教程第5版李春葆答案柄),HDC(设备表线程撕裂者述句柄),HICON (图标句柄)等。这傍边还有⼀个通⽤的句柄,便是HANDLE线程安全
中心办法:-
dispatch_sour源码编辑器编程猫下载ce_create
创立源 -
dispatch_source_set_线程event_handler
设置源作业回调 -
dispatch_source_merge_data
源作业设置数据 -
dispatch_so线程同步urce_get_data
获取源作业数据 -
dispatch_resume
持续 -
dispatch_suspend
挂起
运用示例:
- (void)viewDidLoad { [super viewDidLoad]; self.to线程池的创立办法有几种talComplete = 0; self.queue源码之家 = dispatch_qu线程和进程的差异是什么eue_create("td数据结构难学吗.com", NULL); /* DISPATCH_SOURCE_TYPE_DATA_ADD 自定义线程同步的作业,变量增加 DISPATCH_SOURCE_TYPE_DATA_OR 自定义的作业,变量OR DISPATCH_SOURCE_TYPE_DATA_REPLACE 自定义的作业,变量Replace DISPATCH_SOURCE_TYPE_MACH_SEND MACH端口发送 DI数据结构SPATCH_SOURCE_TYPE_MACH_RECV MACH端口接收 DISPATCH_SOURCE_TYPE_MEMORYPRESSURE 内存报警 DISPATCH_SOURCE_TYPE_PROC 进程监听,如进程的退出、创立一个或更多的子线程、进程收到UNIX信号 DIS数据结构严蔚敏PATCH_SOURCE_TYPE_READ IO操作,如对文件线程和进程的差异是什么的操作、socket操作的读照顾 DISPATCH_SOURCE_TYPE_SIGNAL 接收到UNIX信号时照顾 D数据结构c语言版第二版课后答案ISPATCH_SOURCE_TYPE_TIMER 定时器 DISPATCH_SOURCE_TYPE_VNODE 文件状况监听,文件被删去、移动、重命名 DISPATCH_SOURCE_TYPE_WRITE IO操作,如对文件的操作、socket操作的写照顾 DISPATCH源码年代_MACH_SEND_DEAD */ sel线程池参数f.source = dispatch_source_create(DISPATCH_SO数据结构知识点总结URCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_qu线程池e源码编辑器编程猫下载ue()); dis线程撕裂者patc线程是什么意思h_source_set_event_handler(self.source, ^{ NSLog(@"%@",[NSThread currentThread]); NSUInteger value源码本钱 = dispatch_source_get源码编辑器编程猫下载_data(self.source); se线程池lf.totalComplete数据结构c语言版严蔚敏 += value; NSLog(@"进展: %源码之家.2f",self.totalComplete/100.0)线程和进程的差异是什么; self.progr线程池面试题essView.progress = self.totalComplete/100.0; }); self.isRunning = YES; dispatch_resume(s数据结构期末考试题及答案elf.source); } - (IBAction)didCl线程ickStartOrPauseAction:(id)sen数据结构严蔚敏der源码集市 { if (self.isRunni数据结构c语言版ng) { dispatch_suspend(self.source); dispatch_suspend(sel源码编辑器f.queue); NSLog(@"现已暂停"); self.isRunning = NO; [sender setTi源码本钱tl源码分享网e:@"暂停中.." forState:UIControlStateNormal数据结构c语言版严蔚敏]; }else{ dispatch数据结构题库及答案_resum数据结构教程第5版李春葆答案e(self.source); dispatch_resume(self.queue); NSLog(@"现线程安全已实施了"); self.isRunning = YE线程池面试题S; [s源码之家ender setTi数据结构知识点总结tle:@"暂停中..数据结构与算法" forState:UIControlStateNormal]; } } - (void)touchesBegan源码本钱:(NSSet<U源码超市ITouch *> *)touches数据结构题库及答案 withEvent:(UIEvent *)event{ NSLog(@"开端了"); fo数据结构c语言版r (int i= 0; i<100; i++) { dispatch_async(self.queue, ^数据结构与算法{ if (!self.isRunning) { NSLog(@"现已暂停"); return; } sleep(1); dispatch_source_merge_data(self.source, 1); }); } }
-