美文网首页
多线程-理论

多线程-理论

作者: i爱吃土豆的猫 | 来源:发表于2021-04-11 19:31 被阅读0次

多线程
GCD---同步/异步 ,串行/并发

1.死锁
2.延时函数(dispatch_after)
3.使用dispatch_once实现单例
4.dispatch_barrier_async
5.dispatch_group_async

enter和 leave, 然后 notify 方法通知回调

1. 线程间通信的体现

1.1个线程传递数据给另1个线程
2.在1个线程中执行完特定任务后,转到另1个线程继续执行任务

线程间通信常用方法

-  (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
-  (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
image.png

2. GCD 对比 NSOprationQueue

我们要明确NSOperationQueue与GCD之间的关系
GCD是面向底层的C语言的API,NSOpertaionQueue用GCD构建封装的,面向对象, 是GCD的高级抽象。
1、GCD执行效率更高,而且由于队列中执行的是由block构成的任务,这是一个轻量级的数据结构,写起来更方便
2、GCD只支持FIFO的队列,而NSOperationQueue可以通过设置最大并发数,设置优先级,添加依赖关系等调整执行顺序
3、NSOperationQueue甚至可以跨队列设置依赖关系,但是GCD只能通过设置串行队列,或者在队列内添加barrier(dispatch_barrier_async)任务,才能控制执行顺序,较为复杂
4、NSOperationQueue因为面向对象,所以支持KVO,可以监测operation是否正在执行(isExecuted)、是否结束(isFinished)、是否取消(isCanceld)

实际项目开发中,很多时候只是会用到异步操作,不会有特别复杂的线程关系管理,所以苹果推崇的且优化完善、运行快速的GCD是首选
如果考虑异步操作之间的事务性,顺序行,依赖关系,比如多线程并发下载,GCD需要自己写更多的代码来实现,而NSOperationQueue已经内建了这些支持
不论是GCD还是NSOperationQueue,我们接触的都是任务和队列,都没有直接接触到线程,事实上线程管理也的确不需要我们操心,系统对于线程的创建,调度管理和释放都做得很好。而NSThread需要我们自己去管理线程的生命周期,还要考虑线程同步、加锁问题,造成一些性能上的开销

1.可以队列组和依赖, 但是比较麻烦, 最好用 dispatch_barrier, 栅栏的方式
2.网络请求本身已经封装好是异步的了, 任务会立即完成, 但是数据还没有返回回来, 一种方式是把网络请求转为同步, 捕获正确的完成时间, 一种是使用正确的信号量
3.并发是多个任务在同一时间间隔发生的,如单CPU处理多线程,
并行是多个任务在同一时刻发生的, 如多CPU处理多线程.
4.死锁, 在主线程让主线程执行同步任务

同步和异步 , 是否开启了新的线程?

1.多个网络请求完成后执行下一步?
使用GCD的dispatch_group
每次网络请求都先dispatch_group_enter, 请求回调后再dispatch_group_leave, 这个两个必须配合使用, 两个完成之后这个 group 会自动释放, 当所有的完成之后, 会调用的dispatch_group_notifiy 方法, 通过这个 block, 拿到最终的数据

2.多个网络请求顺序执行后执行下一步
使用信号量 semaphore
每一次遍历, 都让其dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER), 这个线程会等待, 阻塞当前线程, 知道dispatch_semaphore_signal, 调用之后

3.异步操作两组数据时, 执行完第一组之后, 才能执行第二组
dispatch_barrier_async 栅栏的方法

死锁
最常见的就是 同步函数 + 主队列 的组合,本质是队列阻塞。
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2");
});

NSLog(@"1");
// 什么也不会打印,直接报错

4.GCD执行原理?
GCD有一个底层线程池,这个池中存放的是一个个的线程。之所以称为“池”,很容易理解出这个“池”中的线程是可以重用的,当一段时间后这个线程没有被调用胡话,这个线程就会被销毁。注意:开多少条线程是由底层线程池决定的(线程建议控制再3~5条),池是系统自动来维护,不需要我们程序员来维护(看到这句话是不是很开心?) 而我们程序员需要关心的是什么呢?我们只关心的是向队列中添加任务,队列调度即可。

如果队列中存放的是同步任务,则任务出队后,底层线程池中会提供一条线程供这个任务执行,任务执行完毕后这条线程再回到线程池。这样队列中的任务反复调度,因为是同步的,所以当我们用currentThread打印的时候,就是同一条线程。

如果队列中存放的是异步的任务,(注意异步可以开线程),当任务出队后,底层线程池会提供一个线程供任务执行,因为是异步执行,队列中的任务不需等待当前任务执行完毕就可以调度下一个任务,这时底层线程池中会再次提供一个线程供第二个任务执行,执行完毕后再回到底层线程池中。

这样就对线程完成一个复用,而不需要每一个任务执行都开启新的线程,也就从而节约的系统的开销,提高了效率。在iOS7.0的时候,使用GCD系统通常只能开58条线程,iOS8.0以后,系统可以开启很多条线程,但是实在开发应用中,建议开启线程条数:35条最为合理。

block就是能够读取其它函数内部变量的函数

相关文章

  • 多线程-理论

    多线程GCD---同步/异步 ,串行/并发 1.死锁 2.延时函数(dispatch_after) 3.使用dis...

  • 多线程(理论篇)

    1.什么是进程,什么是线程?进程是一个正在运行的应用程序,一个应用程序可以对应一个或多个进程。应用程序是一个没有生...

  • iOS-多线程

    本文主要介绍了 iOS的多线程方案, 多线程安全方案, 多读单写方案. 篇幅稍长,还请耐心看完. 进程 理论上,每...

  • iOS开发之多线程GCD

    前言 iOS开发之多线程理论部分 NSOperation NSThread 什么是GCD 全称是Grand Cen...

  • 线程和多线程理论

    1.线程和多线程定义 线程是程序中一个单一的顺序控制流程。进程内有一个相对独立的、可调度的执行单元,是系统独立调度...

  • 多线程理论基础

    几个基础问题 cpu 核心和线程数 以前 现在 CPU 轮转机制 并发和并行 Java 默认就是多线程的 如何控制...

  • Java 面试系列:Java 中的各种锁和 CAS + 面试题

    如果说快速理解多线程有什么捷径的话,那本文介绍的各种锁无疑是其中之一,它不但为我们开发多线程程序提供理论支持,还是...

  • SpringBoot2.X整合线程池(ThreadPoolTas

    我们在JDK中,可以使用ThreadPoolExecutor提供线程池服务,相关理论,可以在多线程——线程池Thr...

  • iOS-详解多线程---【pthread、NSThread】

    1.多线程理论基础 本质:CPU把时间分成小片,由于同一时间,CPU只能处理一个线程。多线程就是让CPU快速的在多...

  • 多线程的理论基础

    转载自:https://juejin.im/post/5aa75d5af265da23906bad44 (一)CP...

网友评论

      本文标题:多线程-理论

      本文链接:https://www.haomeiwen.com/subject/mjosvhtx.html