OC 底层原理 20:GCD函数和队列

721 阅读3分钟

开发中,我们常用GCD来处理一些异步流程,感觉很熟悉,但是又很陌生。一些概念还是很模糊,比如GCD是什么,任务是什么,串行队列并发队列区别,同步函数和异步函数,队列和函数的配合使用,GCD下层封装等等。本篇我们来逐一分析。

1.GCD相关概念

1.1GCD

GCD全称是 Grand Central Dispatch,纯C语⾔,提供了⾮常多强⼤的函数。

GCD的优势:

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

总结:GCD将任务添加到队列,并指定执行任务的函数。

1.2 任务

GCD任务封装成了blockblock没有参数也没有返回值。任务通过队列的调度,由线程来执行。

任务是如何封装并调用的呢?这是一个问题!

1.3 函数

执行任务的函数分为:异步函数和同步函数

  • 异步函数dispatch_async

    • 不⽤等待当前语句执⾏完毕,就可以执⾏下⼀条语句
    • 会开启线程执⾏ block 的任务
    • 异步是多线程的代名词
  • 同步函数dispatch_sync

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

1.4 队列

队列分为两种:串行队列并发队列。不同的队列中,任务排列的方式是不一样的,任务通过队列的调度,由线程池安排的线程来执行。

不管是串行队列还是并发队列,都会遵循FIFO的原则,即先进入先调度的原则;任务的执行速度或者说执行时长,与各自任务的复杂度有关。

  • 串行队列:通路比较窄,任务按照一定的顺序进行排列,一个一个执行
  • 并发队列:通道比较广,同一时间可有多个任务执行

8888.png

队列是什么,如何封装的,如何调度任务的,这也是我们需要研究的内容。

1.5 队列与函数

上面理解了队列、函数、任务的区别,队列用来调用任务,函数用来执行任务。那么队列和函数不同的配合会有怎样的运行效果呢?

  • 同步函数串行队列

    1. 不会开启线程,在当前线程中执行任务
    2. 任务串行执行,任务一个接着一个执行
    3. 会产生阻塞
  • 同步函数并发队列

    1. 不会开启线程,在当前线程中执行任务
    2. 任务一个接着一个执行
  • 异步函数串行队列

    1. 会开启一个线程
    2. 任务一个接着一个执行
  • 异步函数并发队列

    1. 开启线程,在当前线程执行任务
    2. 任务异步执行,没有顺序,CPU调度有关

2. GCD相关案例分析

2.1 主队列添加同步任务

在当前的主线程中添加一个任务,并同步执行该任务会怎么样呢?会崩!见下图:

Xnip2022-07-26_22-14-42.png

因为在当前的流程中,默认队列就是主队列,也是一个串行队列,任务执行的顺序是:

  1. NSlog(@"0")
  2. dispathc_sync任务块
  3. NSlog(@"2")

而此时第二步中的 块任务 dispathc_syncmainThreadSyncTest 相互等待,也就是我们常说的死锁