关于多线程的理解(不定时更新)

下面会以一小个一小个的知识点进行表达(可能想到哪就写到哪)


1.每一个程序都相当于一个进程,每个进程,系统都会为其分配独立的内存空间运行,所以,ios中每一个app应用都相当于一个进程。

2.一个进程中运行的所有任务都是在线程(Thread)中进行的,每个进程至少有一个线程,也就是所谓的主线程,(下图)


进程、线程的关系


3.app一旦开始运行,就会默认开启一条线程、也就是所谓的“主线程”。主线程的任务一般是:刷新UI;处理UI事件(滑动屏幕、点击....)

4.如果主线程中的操作太多,会造成页面的卡顿、发烫等现象,所以我们会把耗时的任务放在子线程中并发执行,待执行完毕再通知主线程做相应的变化

5.线程是程序执行流的最小单元,是进程中的一个实体。有自己的栈和寄存器.




进阶


多线程的优点:

1.因为可以并发  所以提高了程序的执行效率

2.提高资源的利用率

3.耗时多的任务可以放在线程中,这样不会造成程序卡顿


多线程的缺点

1.线程越多,CPU在调度线程上的开销就越大,占用的内存空间越大

2.线程越多,程序设计就越复杂,比如线程之间的通信,多线程的数据共享,这些都需要程序的处理,增加了程序的复杂度。


多线程的种类

1.PThread:(C语言)

2.NSThread

3.GCD

4.NSOpreation



NSThread

三种开启方法:

1.动态开启:手动开启

NSThread*thread1 = [[NSThrea dalloc] initWithTarget:selfselector:@selector(doSomething1:) object:(@"NSThread1")];[thread1 start];

2.静态开启:创建好直接开启

[NSThread detachNewThreadSelector:@selector(doSomething2:) toTarget:selfwithObject:(@"NSTread2")];

3.隐式开启:创建后直接开启

[selfperformSelectorInBackground:@selector(doSomething3:) withObject:(@"NSTread3")];


【NSthread currentThread】:当前线程 【NSthread mainThread】:主线程


线程之间通信

//在指定线程上执行操作

[self performSelector:@selector(run) onThread:thread withObject:nilwaitUntilDone:YES];

//在主线程上执行操作

[self performSelectorOnMainThread:@selector(run) withObject:nilwaitUntilDone:YES];

//在当前线程执行操作

[self performSelector:@selector(run) withObject:nil];


GCD(Grand Central Dispatch)

优点:

1.自动管理线程的生命周期

2.可用于多核运算


串行队列:(主队列、主线程)先进先出   当执行完一个任务时候 再接着往下进行下一个任务

并行队列:



异常一

如上代码:会崩溃  

分析崩溃原因:

所有的程序,默认就一个主队列和一个主线程,因此viewDidLoad函数这段任务就在主队列中同步执行,dispatch_sync...这段代码表示把B处任务加入主队列中,并且同步执行,这就出问题,B处任务要等主队列中同步执行之前的case1这段任务结束后执行,但B处任务在case1这段任务中,case1又要等B处任务执行完才能继续执行。case1任务要等B处完成才能继续,但case1又排在B处前面,这就尴尬了,所以gg了 😂


GCD 重点

只要是串行队列,肯定要等上一个任务执行完成,才能开始下一个任务。但是并行队列当上一个任务开始执行后,下一个任务就可以开始执行。

同步+串行:未开辟新线程,串行执行任务;

同步+并行:未开辟新线程,串行执行任务;

异步+串行:新开辟一条线程,串行执行任务;

异步+并行:开辟多条新线程,并行执行任务;

在主线程中同步使用主队列执行任务,会造成死锁。


GCD延时方法:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

// 2.0秒后异步追加任务代码到主队列,并开始执行

NSLog(@"after---%@",[NSThreadcurrentThread]);// 打印当前线程

});


dispatch_once:生命周期只执行一次

此方法一般多用于创建单例的时候

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

NSLog(@"就一次%@",[NSThreadcurrentThread]);

 });


NSOperation(操作) 和 NSOperationQueue(操作队列)

NSOperation(任务)、NSOperationQueue(队列)是OC对GCD的封装。

NSOperation是一个抽象类;但是想要使用操作的话  可以用“NSInvocationOperation”“NSBlockOperation”

NSInvocationOperation和NSBlockOperation  在没有配合NSOperationQueue使用时  都是在当前线程中执行;

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];

[operation start];

NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@", [NSThread currentThread]); }]; 

[operation start]; 


NSOperationQueue的使用

添加任务:

1.- (void)addOperation:(NSOperation *)op;//添加操作任务

2.- (void)addOperationWithBlock:(void (^)(void))block;//不需要先创建操作,直接添加block

根据maxConcurrentOperationCount来控制是并发或者串行

maxConcurrentOperationCount = 1:代表串行

maxConcurrentOperationCount默认是-1;当大于1的时候 代表是并发


NSOperation之间的依赖:B以来A的时候  就等A执行完再执行B;注意不能相互依赖  这样会造成死锁


NSOperation 常用属性和方法

取消操作方法

- (void)cancel;实质是标记 isCancelled 状态。

判断操作状态方法

- (BOOL)isFinished;判断操作是否已经结束。

- (BOOL)isCancelled;判断操作是否已经标记为取消。

- (BOOL)isExecuting;判断操作是否正在在运行。

- (BOOL)isReady;判断操作是否处于准备就绪状态,这个值和操作的依赖关系相关。

操作同步

- (void)waitUntilFinished;阻塞当前线程,直到该操作结束。可用于线程执行顺序的同步。

- (void)setCompletionBlock:(void (^)(void))block;completionBlock 会在当前操作执行完毕时执行 completionBlock。

- (void)addDependency:(NSOperation *)op;添加依赖,使当前操作依赖于操作 op 的完成。

- (void)removeDependency:(NSOperation *)op;移除依赖,取消当前操作对操作 op 的依赖。

@property (readonly, copy) NSArray<NSOperation *> *dependencies;在当前操作开始执行之前完成执行的所有操作对象数组。

5.9 NSOperationQueue 常用属性和方法

取消/暂停/恢复操作

- (void)cancelAllOperations;可以取消队列的所有操作。

- (BOOL)isSuspended;判断队列是否处于暂停状态。 YES 为暂停状态,NO 为恢复状态。

- (void)setSuspended:(BOOL)b;可设置操作的暂停和恢复,YES 代表暂停队列,NO 代表恢复队列。

操作同步

- (void)waitUntilAllOperationsAreFinished;阻塞当前线程,直到队列中的操作全部执行完毕。

添加/获取操作

- (void)addOperationWithBlock:(void (^)(void))block;向队列中添加一个 NSBlockOperation 类型操作对象。

- (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait;向队列中添加操作数组,wait 标志是否阻塞当前线程直到所有操作结束

- (NSArray *)operations;当前在队列中的操作数组(某个操作执行结束后会自动从这个数组清除)。

- (NSUInteger)operationCount;当前队列中的操作数。

获取队列

+ (id)currentQueue;获取当前队列,如果当前线程不是在 NSOperationQueue 上运行则返回 nil。

+ (id)mainQueue;获取主队列。



附加知识:

队列组  dispatch_group_t

当把队列任务添加进队列组的时候  当所有添加的任务完成的时候  会有通知回调dispatch_group_notify 

实际应用案例(下载两张图片,当两张图都下载完成的时候 就行拼接得出新的图片)

实现步骤如下:

1.创建一个队列组:

2.在全局队列异步中添加一个任务(下载image1),并添加进队列组

3.在全局队列中异步添加一个任务(下载image2),并添加进队列组

4.当都下载完成的时候  进行回调dispatch_group_notify (这时候就行图片拼接)


dispatch_barrier_async   栅栏函数:

栅栏函数,使用此方法创建的任务,会查找当前队列中有没有其他任务要执行,如果有,则等待已有任务执行完毕后再执行,同时,在此任务之后进入队列的任务,需要等待此任务执行完成后,才能执行

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容