一、GCD
1、同步/异步 和 串行/并发
1)、GCD调用的四种组合
dispatch_sync(serial_queue,^{…}); 同步调用串行队列
dispatch_async(serial_queue,^{…});异步调用串行队列
dispatch_sync(concurrent_queue,^{…});
dispatch_async(concurrent_queue,^{…});
2)、dispatch_sync(serial_queue,^{…}); 同步调用串行队列
回答出死锁的6分,还要回答出为什么死锁才能满分。死锁原因如下:
3)、dispatch_async(serial_queue,^{…});异步调用串行队列
下面代码不会像同步串行一样产生死锁。
4)、dispatch_async(concurrent_queue,^{…});异步并发
为什么printLog函数不执行呢?因为不管GCD通过哪个队列执行,最终都会在底层的线程中执行,但是底层线程默认没有开启runLoop,所以perform函数不执行。
2、dispatch_barrier_async
1)、怎样通过GCD实现多读单写?
dispatch_barrier_async(concurrent_queue,^{//写操作})
读操作为什么不用异步呢?因为读操作需要立即返回结果。而并发队列保证了多个线程可以并发执行。
3、dispatch_group相关知识点
1)、使用GCD实现这个需求?A、B、C三个任务并发,完成后执行任务D?
我认为作者的讲解是错的,作者的代码只能保证block执行完成后开始执行D操作,并不能保证图片都下载成功后去执行D操作。
二、NSOperation
1、主要优点
a、可以添加任务依赖
b、可以控制任务执行状态:isReady、isExecuting、isFinished、isCancelled。如果只重写了main方法,则系统会控制任务执行状态的变化以及任务的退出。如果重写了start方法,则需要自行控制任务状态。
c、可以控制最大并发量
2、oc源码说明系统如何控制任务状态
该处源码解读基于gnustep-base-1.24.9版本
_finish方法的实现如下:
3、系统怎样移除一个isFinished=YES的NSOperation的?===网上再搜搜,印证一下!
任务完成后_finish方法通过KVO的方式变更finished状态为YES,系通过通过NSOperation Queue来监听该KVO,然后在合适的时机移除该NSOperation对象。
三、NSThread
NSThread相关的面试问题往往是结合RunLoop来考察的。
1、NSThread的启动流程
2、NSThread实现的常驻线程
比着上图,只是在为NSThread指定的selector中启动RunLoop,如下图
3、NSThread的实现机制,即start方法的解读
该处源码解读基于gnustep-base-1.24.9版本。
线程的启动函数nsthreadLauncher源码如下:
线程的main函数源码如下:
start方法开始做了一些异常的判断,经历了这些异常判断之后,在1201行调用pthread_create函数来创建线程,然后在该函数中调用线程的启动函数nsthreadLauncher,nsthreadLauncher函数中调用线程的main函数,main函数调用创建线程时传进来的selector,如果要实现常驻线程,则在selector中调起RunLoop。
四、多线程与锁
1、iOS中有哪些常用锁?
a、@synchronized:一般在创建单例对象的时候使用。
b、atomic:修饰属性的关键字;对被修饰对象进行原子操作(不负责使用)
c、OSSpinLock:自旋锁,循环等待访问,不释放当前资源==对这个解释我不理解,再搜搜??用于轻量级数据访问,如简单的int值+1/-1操作。
d、NSRecursiveLock:递归锁,特点是可以重入。
e、NSLock:一般用于线程同步。
这个情况可以通过换成递归锁解决。
f、dispatch_semaphore_t:信号量
2、dispatch_semaphore_t讲解
1)、dispatch_semaphore_t常用函数
dispatch_semaphore_create(int value)创建数值为value的信号量;
dispatch_semaphore_wait(semaphore,time)设置当前线程对信号量的等待时间(如DISPATCH_TIME_FOREVER代表永远),如果没有资源则等待;
dispatch_semaphore_singal(semaphore)释放信号量的一个值;
2)、dispatch_semaphore_create()函数
该函数主要用于创建semaphore结构,semaphore结构定义如下:struct semaphore{int value; List
3)、dispatch_semaphore_wait()函数
函数主要实现如图,途中第二句代码的意思是如果信号量的值小于0,则调用该函数的线程主动的将自己阻塞起来。
4)、dispatch_semaphore_singal()函数
函数主要实现如图,途中第二句代码的意思是如果信号量的值小于等于0,则说明有线程处于阻塞状态,通过wakeup函数去唤醒阻塞的线程。唤醒是一个被动实现。
3、iOS系统为我们提供的几种多线程技术各自的特点是怎样的?
1)、GCD用来实现一些简单的线程同步,包括一些子线程的分派,包括实现一些类似于多读单写这种场景的问题
2)、NSOperation和NSOperation Queue由于可以控制任务状态、依赖,所以AFNetwork和SDWebImage内部都使用者两个类实现多线程。
3)、NSThread常用于实现常驻线程。GCD和NSOperation都不能实现常驻线程,因为他们底层都是通过系统的线程池执行任务。