iOS-底层(16):GCD-函数与队列

GCD

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

GCD优势

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

一句话总结就是:
将任务添加到队列,并且指定执行任务的函数

函数

  • 任务使用 block封装,block 没有参数也没有返回值

执行任务的函数异步 dispatch async

  • 不用等待当前语句执行完毕,就可以执行下一条语句
  • 会开启线程执行 block 的任务
  • 异步是多线程的代名词

同步dispatch sync

  • 必须等待当前语句执行完毕,才会执行下一条语句
  • 不会开启线程
  • 在当前执行 block 的任务

队列

队列是一种数据结构 FIFO 先进先调度,
串行和并发队列

  • 串行队列
    任务顺序执行,one by one;
  • 并发队列
    任务随机执行,不需要等待,由CPU调度

队列和线程

任务是在线程中执行,通过队列来调度

函数与队列

image.png

主队列

专⻔⽤来在主线程上调度任务的串⾏队列
不会开启线程
如果当前主线程正在有任务执⾏,那么⽆论主队列中当前被添加了什么任务,都不会被调度
dispatch_get_main_queue();

全局并发队列

为了⽅便程序员的使⽤,苹果提供了全局队列 dispatch_get_global_queue(0, 0)
全局队列是⼀个并发队列
在使⽤多线程开发时,如果对队列没有特殊需求,在执⾏异步任务时,可以直接使⽤全局队

死锁

队列任务的循环等待。

四个条件:

  1. 互斥条件: 一个资源只能被一个线程使用.在一段时间内,资源已被占有.如果此时有请求获取该资源,则该请求只能等待.
  2. 请求与保持条件: 线程已保持了至少一个资源,但又从新提出获取新的资源请求,而该资源已被其他线程占有.此时该请求将被阻塞等待,对于已获得的资源保持不放.
  3. 不可剥夺条件: 线程获得资源在未使用完成之前,不能被其他线程强行剥夺,只能该线程自己放弃.
  4. 循环等待条件: 若干线程形成首尾相接循环等待资源的关系.
    比如下面代码
- (void)textDemo{
    // 同步队列
    dispatch_queue_t queue = dispatch_queue_create("serial", NULL);
    NSLog(@"1");
    // 异步函数
    dispatch_async(queue, ^{
        NSLog(@"2");
        // 同步
        dispatch_sync(queue, ^{
            NSLog(@"3");
        });
//         NSLog(@"4");
    });
    NSLog(@"5");
    
    // 1 5 2 死锁
    //

}

画图分析一下:

image.png

3 加入到串行队列中,等待dispatch_sync 的block执行完毕,而3是同步任务,要立即执行,造成了任务的互相等待,形成死锁
将 4 打开 原理类似。

你可能感兴趣的:(iOS-底层(16):GCD-函数与队列)