• 常见数据结构

    • dispatch_object_t

      GCD一切类的基类
      GCD源码剖析
      源码能够看出dispatch_object_t是一个联合体(并且是一个源码本钱通明联合体线程),便是dispatch_object_t可所以结构体中的任意一种类型,巨细为这些数据类型中最大的数据类型的巨细

    • _os_object_s

      类似于类中的isa指针
      GCD源码剖析

    • dispatch_object_s

      GCD最基础的基类
      GCD源码剖析

    • dispatch_continuation_s

      dispatch_continuation_s结构体首要封装blockfunctiondispatch_async中的bloc线程撕裂者k究竟都会封装成这个数据类型
      GCD源码剖析

    • dispatch_group_s

      GCD源码剖析

    • dispatch源码本钱_queue_s

      GCD源码剖析

  • 创立部队源码剖析

    • dispatch_queue_create源码

      第一步下一个符号断点
      GCD源码剖析
      发现源码在libdisp数据结构难学吗atch.dylib库中,然后下载libdispatch.dylib源码查找dispatch_queue_create能够找到GCD源码剖析其实冲仓库信息中也能够知道接下来调用了_dispatch_lane_create_with_target函数来完毕创立

    • _dispatch_lane_create_with_target源码

      GCD源码剖析大致进程如下:

      1. 标准化参数
      2. 设置方针部队
        调用_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]
      3. 开荒空间创立部队
        _dispatch_obj源码网站ect_alloc开荒空间创立部队
      4. 初始化部队
        _dispatch_queue_init源码始化部队,这儿依据第一步标准后的参数据结构c语言版严蔚敏数判别设置最大并发数,D源码编辑器手机版下载ISPATCH_QUEUE_WIDTH_MAX从这儿也能够知道最大的并发数是4094
        设置部队标识符等
      5. 赋值方针部队
        将上述设置的方针部队赋值

      具体流程图如下:GCD源码剖析

    • 部队和线程之间的联络图

    GCD源码剖析

  • 函数源码剖析

    • 异步函数剖析
      • _dispatch_continuation_init使命包装函数

        首要是copy任线程和进程的差异是什么务,赋值func、ctxt等参数
        GCD源码剖析
        经过_d线程池面试ispatch_continuation_init_f函数赋值func、ctxt等参数
        GCD源码剖析

      • _d数据结构知识点总结ispatch_continuation线程池面试题_async并发处理函数

        GCD源码剖析
        大局查找dx_push发现是数据结构题库及答案个宏#define dx_push(x, y数据结构与算法, z) dx_源码之家vtable(x)->dq_push(x, y, z),发现源码仍是调用了dq_push办法持续大局查找d数据结构c语言版q_pushGCD源码剖析发现dq_push办法有很多个不过每个上面有类型不难猜测异步函数应该对应数据结构c语言版第二版课后答案的是queue_concurrent下的办法对应的办法是_dispatch_lane_concurrent_push这儿能够经过下符号断点来验证首要数据结构严蔚敏现在异数据结构期末考试题及答案步函数钱下个断点GCD源码剖析然后再往下走发现断在了_dispatch_lane_concurr数据结构严蔚敏ent_push的办法仓库上所以也验证了上述猜测GCD源码剖析,持续往下跟,大局查找_dispatch_lane_concurrent_线程池的创立办法有几种pushGCD源码剖析使命实施即出队所以一般并行部队中的异步使命的话都是空的所以假定不增加栅门函数则一般会实施_dispatch_continuation_redirect_push办法这儿也能够线程池面试题经过增加符号断点来验证GCD源码剖析GCD源码剖析GCD源码剖析GCD源码剖析发现确实_di源码集市spatch_lane_concurrent_push办法实施完毕之后直接进入到_dispatch_continuation_redirect_push办法然后就实施了使命持续大局数据结构题库及答案查找_d线程是什么意思ispatch_continuation_redirect_push办法GCD源码剖析此刻的dq_push对应的就不是_dispatch_lane_concurrent_push办法了由于对应的部队类型变成了跟队线程撕裂者伍,所以线程池参数此刻应该对应的是_dispatch_r源码编辑器手机版下载oot_queue_push办法相同的也能够依据上述的进程下一个符号断点来验证线程安全,持续大局查找_dispatch_root_queu源码编辑器e_push办法GCD源码剖析下个_dispatch_ro线程的几种状况ot_queue_pus数据结构期末考试题及答案h_override符号断数据结构难学吗点鄙人一源码编辑器手机版下载_dispatch_root_qu数据结构与算法eue_push_inline符号断点发现会走到_dispatch_root_queue_pu数据结构c语言版严蔚敏sh_override数据结构期末考试题及答案办法中然后GCD源码剖析里面又持续调用了_dispatch_root_queue_push_数据结构与算法inline办法GCD源码剖析持续查找_dispatch_roo线程池的创立办法有几种t_queue_poke办法GCD源码剖析大局查找_dispatch_root_queue_poke_slow办法GCD源码剖析到这儿异步函数创立线程的流程就现已结线程和进程的差异是什么束如下图GCD源码剖析可是此刻仅仅是创立了线程,但线程安全是使命还没有实施此刻再看上方的_dispatch_root_queues_init办法点进去发现发现是数据结构严蔚敏dispatch_onc数据结构c语言版严蔚敏e_f办法调用GCD源码剖析传入的fun源码编辑器编程猫下载c_dispatch_root_queues_init_onceGCD源码剖析,持续进到数据结构c语言版第二版课后答案_dispatch_worker_thread2(线程的实施是体系底层去启航的,这儿只源码编辑器手机版下载需求绑定线程,体系会去触发线程)办法查看源码GCD源码剖析_dispatch_root_queue_drain办法源码GCD源码剖析GCD源码剖析GCD源码剖析究竟发现在这儿调用了使命办法,剖析之前完全能够打数据结构题库及答案断点然后打印仓库调用状况然后再去源码中找对应代码源码网站,仓库调用状况如下:GCD源码剖析发现仓库的调用状况就和上述剖析的流程共数据结构c语言版严蔚敏同,
        总流程图如下:线程池面试题GCD源码剖析

    • 同步函数剖析

      首要看dispatch_sync源码GCD源码剖析持续看_dispatch_sync_f源码GCD源码剖析GCD源码剖析发现同步函数据结构c语言版第二版课后答案数的当地便是经过栅门函数来完毕的(栅门函数源码如下源码之家)

  • 栅门函数源码剖析

    • 同步栅门函数有必要自己的block使命实施完毕,下面的使命block才会实施,这就标明同步堵塞的是当时的线程
    • 异步栅门函数不需求等自己的使命block实施,下面的代码会接着实施,这就标明异步堵塞的是部队(queue)。

    留神:栅门函数只能用在并发自定义部队数据结构题库及答案中,大局并发部队,假定堵塞了其他体系使命,会形成其他使命,串行部队运用栅门函数等于没用
    dispatch_bar线程的几种状况rier_sync源码如下源码之家GCD源码剖析GCD源码剖析GCD源码剖析GCD源码剖析
    同步栅门函数源码流程:GCD源码剖析

  • 死锁源码剖析

    上述栅门函数源码编辑器手机版下载剖析得知死锁在_dispatch_sync_f_slow办法中处理的GCD源码剖析首要将当时使命增加到部队中然后实施__DISPATCH_WAIT_FOR_QUEUE__办法GCD源码剖析再看_dq_state_drain_locked_by办法源码GCD源码剖析GCD源码剖析判别dq是否为正在等候的部队源码编辑器手机版下载,然后给出一个状况state,然后将dq的状况和数据结构严蔚敏当时使命依托的部队进行匹配,匹配成功则抛出失常

  • 单列源码剖析

    大局查找dispatch_once查看源码GCD源码剖析一同发现_dispatch_Block_i线程的几种状况nvoke便是一数据结构c语言版严蔚敏个宏#defi线程撕裂者ne _dispatch_Block_invoke(bb) (线程池的创立办法有几种(dispatch_function_t数据结构期末考试题及答案)((struct Block_layout *)bb)->invoke)便是invoke办法GCD源码剖析GCD源码剖析GCD源码剖析GCD源码剖析GCD源码剖析
    单例底层完毕流程图GCD源码剖析

  • 信号量

    控制最大并发量(一般运用不多)中心函数如下:

    1. dispatch_semaphore_create 创立信号量,指定最大并发数
    2. dispatch_semaphore_signal 发送信号
    3. 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);
    });
    }
    

    打印效果源码本钱如下:GCD源码剖析能够发现由于控制最大的并发量是2所以能一同实施的使命有两个,此刻使命一和使命2是一同实施的,使命三是比及前两个使命实施线程的几种状况完毕之后再实施的
    源码剖析:

    1. dispatch_semap数据结构严蔚敏hore_create

      首要是初始化作业,设置最大并发量(最大并发量要大于0),封装成dispatch_semaphore_t结构体
      GCD源码剖析

    2. dispatch_semaphore_wait

      首要是对并发量进行–操作,假定当时的并发量现已小于0了阐明当时现已达到了最大并发量,所以使命进行无限等候源码编辑器状况(堵塞线程)源码如下GCD源码剖析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
      
    3. dispatch_semaphore_signal

      dispatch_semaphore_wait相反,首要是对并发量进行加加操作
      GCD源码剖析

  • 调度组

    调度组首要的效果便是监听某些使命实施状况,比如现在需求改写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_leavedispatch_group_enter需求成对出现
    运用示例:

    1. 正常状况示例源码年代
      
      

      打印状况:
      GCD源码剖析

    2. 运用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实施完毕(主线程)");
      

      打印效果:
      GCD源码剖析

    3. 特别状况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实数据结构与算法行完毕(主线程)");数据结构严蔚敏
      

      打印效果:
      GCD源码剖析
      阐明奉告放在最前面只需实施dispatch_group_leave就会实施奉告

    4. 特别状况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实施完毕(主线程)");
      

      打印状况:
      GCD源码剖析
      发现dispatch_group_notify一贯都不会实施

    5. 特别状况2(多一个)dispatch_group_leave
      GCD源码剖析
      直接会溃散,所以说dispatch_group_leavedispatch_group_ente源码网站r一定要成数据结构教程第5版李春葆答案对出现

    源码探究:

    • dispatch_group_cr数据结构eate

      GCD源码剖析GCD源码剖析

    • dispatch_group_e源码分享网nter

      GCD源码剖析GCD源码剖析GCD源码剖析

    • dispatch_grou线程的几种状况p_leave

      GCD源码剖析GCD源码剖析

    • d线程撕裂者ispatch_源码编辑器手机版下载group_async

      相当于帮开发者省去了dispatch_gr线程和进程的差异是什么oup_enterdispatch_group_lea数据结构ve两个办法的调用线程池面试题
      GCD源码剖析GCD源码剖析GCD源码剖析
      发现底层在创立之前调用了dispatch_group_enter办法
      GCD源码剖析
      然后再使命实施完毕之后又调用了dispatch_group数据结构_leave

    • dispatch_group_notify

      GCD源码剖析GCD源码剖析

  • Dispatch Source源码网站

    在任⼀线程上调⽤它的的⼀个函数dispatch_source_merge_data后,会执⾏ Dispatch Source 事前定义好的句柄(能够把句柄简略理解为⼀个 block )这个进程叫Custom event,⽤户作业。是dispatch source⽀持处理的⼀种作业
    句柄是⼀种指向指针的指针 它指向的便是⼀个类或许结构,它和体系有很密切的联络 HINSTANCE(实线程是什么意思例句柄),HBITMAP(位图句数据结构教程第5版李春葆答案柄),HDC(设备表线程撕裂者述句柄),HICON (图标句柄)等。这傍边还有⼀个通⽤的句柄,便是HANDLE线程安全
    中心办法:

    1. dispatch_sour源码编辑器编程猫下载ce_create创立源
    2. dispatch_source_set_线程event_handler设置源作业回调
    3. dispatch_source_merge_data源作业设置数据
    4. dispatch_so线程同步urce_get_data获取源作业数据
    5. dispatch_resume持续
    6. 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);
    });
    }
    }