多线程编程与GCD|青训营笔记

65 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的的第5天

多线程编程与GCD

1.进程与线程

进程:程序运行的一个实例,是资源分配的最小单位,独立地运行在其专用受保护的内存空间内线程;一个进程可以包含多个线程,线程是操作系统实施调度的最小单位。

各个线程之间共享进程的内存空间以及一些进程的资源,每个线程都有寄存器、栈、线程局部存储(TLS)等私有数据

2.串行、并行、并发

串行:任务有序地一个一个地执行,前一个执行完才能执行下一个

并行:多个任务在同一时刻被执行

并发:多个任务在同一时间段内需要被执行,侧重年是“发生”

多线程编程又称并发编程,让多个CPU并发处理多个线程的指令,从而提高程序的执行效率

RunLoop是事件接收和分发机制的一个实现,可以让线程在适当的时间处理任务不会退出,iOS App中,主线程的RunLoop在程序运行时就会启动,其他线程的RunLoop需要手动开启。

!不要在主线程的RunLoop中进行耗时操作,会妨碍主线程中的主循环的执行,从而引起App卡顿问题

GCD

GCD抽象出了任务、队列等概念、将并发编程等范式变为了定义想执行的任务并追加到适当的派发队列。

1.任务与队列

任务:在线程中执行的代买,在GCD API中一block的形式提交到队列

队列:任务派发队列(先进先出,First In First Out),任务追加到派发队列后按照先进先出的次序派发到队列线程进行处理。

2.串行队列和并发队列

串行队列:队列中的任务在单个线程中顺序执行,执行的中的任务结束后才能继续执行下一个任务

并发队列:队列中的任务在异步执行的情况下可以分发到多个线程下同时执行

Main Dispatch Queue: dispatch_get_main_queue():主队列,串行队列,任务只在主线程中执行。

Global Dispatch Queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH/DEFAULT/LOW/BACKGROUND, 0);四种不同优先级的并发队列 

3.同步执行和异步执行

同步执行(dispatch_sync):提交任务到指定队列,在该任务执行结束之前会一直等待;提交的任务只能在当前任务只能在当前线程执行,不具备开启线程的能力

异步执行(dispatch_async):提交任务到指定队列,继续往下执行不等待任务执行结束;可以在新的线程中执行任务,具备开启线程的能力 

Dispatch_group

1.dispatch group notify

希望一个Queue中所有任务执行完成或者多个queue中所有任务执行完成后再执行某任务,可以通过dispatch_group、dispatch_group_notify实现

先创建group:dispatch_group_t group = dispatch_group_create();

然追加任务到group:dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_async(group, queue, block0);

dispatch_group_async(group, queue, block1);

dispatch_group_async(group, queue, block2);

group 中所有任务执行完成之后才在主线程执行操作

dispatch_queue_t mainQueue = dispatch_get_**main**_queue();

dispatch_group_notify(group, mainQueue, ^{

NSLog(@"done");

});

2.dispatch group wait

\

3.dispatch apply

!注意在dispatch_sync(globalQueue,中执行dispatch_apply会导致程序死锁,函数等待追加的任务处理结束)

线程安全与同步

`Atomic & Nonatomic

Atomic对属性getter、setter调用是线程安全的,需要耗费资源为属性加锁;nonatomic访问不是线程安全的,但访问效率比atomic更高

·dispatch_barrier_async

考虑多线程进行数据读写的场景,多个写操作不能并发执行,写操作和读操作不能并发执行,但是多个读操作是可以并发执行的,此时可以使用 dispatch_ barrier_async 同时满足提高读操作效率和保证线程安全的要求dispatch_ barrier_async 函数会等队列中的全部任务执行结束后,再将指定的任务 × 追加到队列,之后提交的任务也需要等待X执行结束

`Dispatch Semaphore

在GCD中利用dispatch_semaphore可以实现线程同步,控制并发线程数量的效果,在iOS中表现较好较为常用