关于GCD的使用(该文章仅作为个人笔记,更多原理资料请查看文章尾部的《相关资料》)

来源:互联网 发布:java打印预览excel 编辑:程序博客网 时间:2024/05/16 11:52

多线程相关概念:

1、进程与线程

1、进程概念:进程是程序在计算机上的一次执行活动;打开一个app,就开启了一个进程,一个进程可包含多个线程。
2、线程概念:独立执行的代码片段,一个线程同时间只能执行一个任务,同理多线程并发就可以在同一时间执行多个任务。

3、IOS程序中主线程(mainThread)主要处理UI事件,显示和刷新UI;子线程(Thread)多用于处理耗时任务,可以提高资源利用率;
主线程的堆栈大小是1M,第二个线程开始都是512KB,并且该值不能通过“编译器”或者“线程API函数”来更改。

2、多线程中会出现的问题

1、Critical Section(临界代码段)
指的是不能同时被两个线程访问的代码段,比如一个变量,被并发进程访问后可能会改变变量值,造成数据污染,则该变量的值不再可信(数据共享问题)。
2、Race Condition(竞态条件)
当多线程同时访问共享数据是,会发生争用的情形;第一个线程改变了一个变量值,第二个线程也读取改变了这个变量值;即,两个线程同时操作了该变量,此时她们会发生竞争,确定最终是哪个线程写入的值会被保留。
3、Deadlock(死锁)
两个(多个)线程都要等待对方完成某个操作才能进行下一步,此时会发生死锁。

4、IMutable对象都是线程安全的;但,Mutable对象都是非线程安全的,使用Mutable对象,一定要用同步锁来同步访问(@synchronized)。

5、线程安全的代码(对象),可以背多个线程或并发的任务调度;非线程安全的只能按次序被访问。

6、原子属性(atomic)加锁
原子属性,为setter方法加锁,将属性以atomic的形势声明,该属性变量就能支持互斥锁了。


多线程编程技术的优缺点比较

1、NSThread(抽象层次:低)
1、优点:轻量级,使用简易,可以直接操作线程对象
2、缺点:需要自己管理线程的生命周期以及线程同步;线程同步对“数据的加锁”会有一定的开销。


2、Cocoa NSOperation(抽象层次:中)
优点:不需要关心线程管理、数据同步的事情;可以把精力放在需要执行的操作上。基于GCD,是对GCD的封装,比GCD更加面相对象。

3、GCD全称Grand Center Dispatch(抽象层次:高。因此苹果推荐使用GCD)
1、优点:是一种多核编程模式;使用简易,效率高,速度快,基于C语言,更底层更高效;自动管理线程的生命周期(创建线程、调度任务、销毁线程)。
2、缺点:如果使用GCD的场景很复杂,就很可能遇到死锁问题。

4、串行、并发队列(queue)和同步(sync)、异步函数(async)
总结:同步(sync)不会创建新的线程
  异步(async):并发队列--多条线程
     串行队列--单线程(主线程除外)


相关的dispatch

1、dispatch_async:多用于避免界面在处理耗时操作时卡死,比如网络数据读取、IO、数据库读写。(然后可以通知主线程更新界面)



2、dispatch_group_async

可以用来监听一组任务是否全部完成了,完成时通知执行其他操作。示例如下:

3、dispatch_barrier_async

dispatch_barrier-async是当在它前面的任务执行结束后,dispatch_barrier-async才执行;并且在dispatch_barrier-async后面的任务必须等它执行完之后,它才执行。


4、dispatch_apply:执行某个代码片段N次

dispatch_apply(N  ,globalQueue  , ^(size_t index)

{

//执行N次

})


5、当程序进入后台时,注册后台任务

在没有使用GCD时,当App被按Home键退出后,app仅有最多5秒的时间做一些保存或清理资源的工作。

但是在使用GCD后,app最多可以有10分钟的时间在后台长久的运行。


关于进程和线程内存:

1、系统中的每一个进程都有自己独立的虚拟内存空间,而同一个进程的多个线程则共用进程的内存空间。

每创建一个新的线程,都需要占用一些内存(如每个线程都有自己的Stack空间)和消耗一定的CPU时间。


关于NSOperation:

1、NSInvocationOperation:初始化(alloc  initWithTarget)

2、NSBlockOperation:初始化(blockOperationWithBlock)

3、任务之间可以添加依赖关系,即线程2依赖于线程1;(执行完)线程1-->线程2(才会执行线程2);注意不要循环依赖,否则不会工作。

4、依赖关系可以跨线程(如:异步线程(线程1)下载网络数据,主线程(线程2)更新界面UI)。




相关资料:

GCD的基本概念以及示意图
GCD的介绍和使用(附带代码示例)
ios多线程网络之GCD的简单介绍(附带概念示意图以及代码示意图)





0 0