大家好,我是面试聊iOS的程序员。
这篇文章将和大家分享面试iOS时聊多线程一般都可以聊些什么。
抖音搜索 面试聊iOS 观看视频版
进程、线程
进程
当一个程序进入内存运行,即变成一个进程。进程是处于运行过程中的程序,并且具有一定独立功能。
线程
线程是进程中的一个执行单元,负责当前进程中程序的之心,一个进程至少有一个线程。一个进程中可以有多个线程。
单线程程序:若有多个任务只能一次执行
多线程程序:若有多个任务,可以同时执行
对于CPU单一个核心而言,某个时刻只能执行一个线程,而CPU在多个线程之间切换的速度相对我们的感觉要快,看上去就是在同一时刻运行。
多线程并不能提高程序的运行速度,但能提高运行效率
任务
任务:执行操作的意思,就是要在线程中执行的代码
同步执行(sync)
- 同步添加任务到队列中,队列在任务结束之前会一直等待,直到任务完成之后再继续执行
- 只能在当前线程中执行任务,不具备开启新线程的能力
异步执行(async)
- 异步添加任务到队列中,队列不会等待,可以继续执行其他任务。
- 可以在新的线程中执行任务,具备开启线程的能力,但不一定开启新线程。
队列
队列(dispatch queue)
执行任务的等待队列,即用来存在任务的队列。队列是一种特殊的线性表,采用FIFO(first in first out)的原则。新的任务总是被插到队列的末尾,读取任务总是从队列的头部开始读取。每读取一个任务,则从队列中释放一个任务。
串行队列(serial dispatch queue)
只开启一个线程,每次只能执行一个任务,一个任务执行完毕后才能执行下一个任务。
并发队列(concurrent dispatch queue)
可以让多个任务并发(同时)执行,可以开启多个线程,并同时执行任务。并行队列的并发功能只能在异步下才有效。
主队列
是一个特殊的串行队列,添加到主队列的任务只能在主线程中执行
任务+队列
同步执行+并发队列:不开启新线程,串行执行任务
同步执行+串行队列:不开启新线程,串行执行任务
同步执行+主队列:线程死锁
异步执行+并发队列:开启新线程,并发执行任务
异步执行+串行队列:开启1条新线程,串行执行任务
异步执行+串行队列:不开启新线程,串行执行任务
队列+任务+任务
并发队列+异步执行+同步执行:不开启新的线程,串行执行任务
并发队列+异步任务+异步任务:开启新线程,并发执行任务
并发队列+同步任务+同步任务:不开启新线程,串行执行任务
并发队列+同步任务+异步任务:开启新线程,并发执行任务
串行队列+异步执行+同步执行:线程死锁
串行队列+异步执行+异步执行:开启1条新线程,串行执行任务
串行队列+同步执行+同步执行:线程死锁
串行队列+同步执行+异步执行:开启1条线程,串行执行
线程安全
在多线程中运行得到的结果与在单线程中运行得到的结果一致,即为线程安全。
GCD信号量
保持线程同步,将异步执行转换为同步执行
保证线程安全,为线程加锁
自旋锁:如果资源被占用,等待的线程以死循环的方式一直处于忙等状态,一旦资源释放,立马执行
互斥锁:如果资源被占用,等待的线程会进入休眠状态,直到等待的资源被解锁才被唤醒
GCD
dispatch_barrier_async
栅栏函数,等待前面加到并发队列中的任务全部执行完毕之后,再将指定的任务追加到该异步队列中。
dispatch_after
延时执行,不是在指定时间之后才开始执行任务,而是在指定时间之后将任务追加到主队列中。
严格来讲,这个时间并不是绝对准确的。
dispatch_once
只执行一次,常用于创建单例,在多线程的环境下,也能保证线程安全
dispatch_apply
快速迭代,可以在多线程中同时(异步)遍历
dispatch_group_notify
监听group中任务的完成状态,当所有任务都执行完后,追加任务到group中并执行
dispatch_group_wait
阻塞当前线程,等待指定的group中的任务执行完成后,才继续往下执行
dispatch_group_enter
表示一个任务追加到group中
dispatch_group_leave
表示一个任务离开group
dispatch_semaphore
信号量
dispatch_semaphore_create
创建信号量并初始化信号总量
dispatch_semaphore_signal
信号量+1
dispatch_semaphore_wait
信号量-1
信号量<0时会一直阻塞所在线程,反之就可以正常执行
NSOperationQueue
NSOperation:操作,即GCD中的任务,将要在线程中执行的代码片段
NSOperationQueue:操作队列,不同于GCD的队列FIFO的原则。对于添加到队列中的操作,首先进入准备就绪的状态(就绪状态取决于操作之间的依赖关系),然后就绪状态的操作的开始执行顺序由操作之间的优先级决定。
没有依赖关系的操作先进入就绪状态,根据优先级决定执行顺序;当前操作依赖的操作执行完毕,当前操作进入就绪状态
通过设置最大并发操作数来控制并发和串行
默认为-1,不做限制,可进行并发执行;==1是串行队列,串行执行;>1是并发队列,并发执行
被添加到队列的操作,默认是异步执行的
主队列运行在主线程
自定义队列同时包含串行、并发的功能,运行在其他线程
通过设置队列的isSuspended属性,可实现队列的暂停与继续的效果,正在执行的操作不受影响
可以取消队列中所有的操作,也可取消单个操作,只对未执行的操作有效; 操作已经在执行中,系统不会强制停止这个操作,只会标记cancelled属性为true。