多线程

作者: QG不吃鱼的猫 | 来源:发表于2020-05-11 18:43 被阅读0次

一、线程 进程

*   一个程序就是一个进程,一个程序的多个任务被称为线程。
*   进程是表示资源分配的基本单元,线程是进程中执行和调度的基本单元。
*   资源分配给进程,同一个进程可以有多个线程,同一个进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储),但是每个线程拥有自己的栈段,栈段又叫做运行时段,用来存储所有的临时变量和局部变量。
*   处理机分配给线程,即真正运行的是线程。线程执行过程中,需要协作同步,不同的进程的线程利用消息通信的方法进行同步。

//最常用的消息通信是 基于 performSelector dispatch_async MachPort 进行主线程和子线程的通信 。
//关于MachPort的细节可以结合runloop再进行讨论。

二、多线程

*  同一时间,CPU只能处理1条线程,多线程并发执行,其实是CPU快速的在多条线程之间进行调度。
*  开启线程需要一定的内存空间,主线程占用1M,子线程占用512KB,如果线程特别多,会占用大量的内存空间,降低程序的性能。

三、任务和队列

队列:这里的队列指执行任务的等待队列,是一种特殊的线形表,采用 FIFO原则。
任务 :执行操作的意思,就是线程中执行的那段代码。

队列包含 :串行队列(包含主队列)、并行队列
任务执行方式 :同步执行、异步执行

组合:

*  串行队列、同步执行 不开启新线程,任务依次执行
*  串行队列、异步执行 开启一个新线程,任务依次执行
*  并行队列、同步执行 不开启新线程,任务依次执行
*  并行队列、异步执行  开启多个新线程,任务并发执行

四、iOS中的多线程

主要有三种,NSThread、NSoperationQueue,GCD

1.NSThread 轻量级别的多线程技术

基本语法

片段1

NSThread *th = [[NSThread alloc] initWithTarget:self selector:@selector(test:) object:@"123"];
th.threadPriority = 1;
th.name = @"new";
[th start];
[th cancel];

[NSThread detachNewThreadSelector:@selector(testThread:) toTarget:self withObject:@"123"];

片段2
  • 当前线程 1秒后执行
    [self performSelector:@selector(aaa) withObject:nil afterDelay:1];
  • 回到主线程
    [self perfomSelectorOnMainThread:@selector(aaa) withObject:nil waitUntilDone:YES];
    *开辟子线程
    [self perfomSelectorInBackground:@selector(aaa) withObject:nil];
    *在指定线程执行
    [self performSelector:@selector(aaa) onThread:[NSThread currentThread] withObject:nil waitUntilDone:YES];
* 构建方式:初始化方式、构造器方式
* 如果是初始化方式,需要自己启动(start)和资源销毁(cancel),threadPriority 0~1。
* 如果是构造器方式,会自动启动。
* performSelector NSObject的子类或者对象都可以调用此方法, 
*  waitUntilDone:YES  如果设置为YES就必须等回调方法执行完毕后再执行后面的代码
* afterDelay 会在内部创建一个NSTimer,然后加到当前线程runloop中,如果没有开启runloop,该方法会失效,也就是在子线程中,需要启动runloop。

2.GCD 对比 NSOpreationQueue

1、两者之间的关系
GCD是面向底层C语言的API,NSOprationQueue用GCD封装构建的,是 GCD的高级抽象。
2、两者之间的区别

  • GCD执行效率更高,写起来也更方便
  • GCD只支持FIFO的队列,而NSOprationQueue可以设置最大并发数,优先级、依赖等调整执行顺序。
  • NSOprationQueue是面向对象的,所以支持KVO,可以检测operation状态,如正在执行(isExecuted)、是否结束(isFinished)、是否取消(isCanceld)
    3、两者之间的选择
  • 实际的项目开发中,很多时候会用用到异步操作,不会有特别复杂的关系管理,所以苹果推崇完善和运行快速的GCD
  • 如果考虑操作之间的事物性,顺序性,依赖关系等,如多线程并发下载,GCD需要自己写更多的代码实现,而NSOpreationQueue已经内建了这些支持。

五、死锁

在串行队列的任务中,执行同步任务,因为串行队列需要等待任务执行结束才能执行下一个任务,所以会造成死锁。

六、栅栏函数 dispatch_barrier_async

使用范例:可以做到多读单写,在写操作中加入barrier。

dispatch_barrier_async和dispatch_barrier_sync 特点
1、两者同样是干预了本队列中任务的执行,都是先执行前面的任务再执行后面的任务。
2、两者之间唯一的区别是,前者不会干预任务的插入,后者必须等待前面的任务执行结束以后才会对后面的任务进行插入。

七、Dispatch Semaphore 信号量

GCD中的信号量是指 Dispatch Semaphore,是持有计数的信号。

提供了三个函数
dispatch_semaphore_create 创建并初始化总量
dispatch_semaphore_signal 发送信号,总量+1
dispatch_semaphore_wait 总量-1,如果总量为0会一直等待。

主要作用:
1同步
2加锁 实现步骤:初始化信号量为1,执行代码段先wait锁住,代码末尾signal放开。

八、延时函数dispatch_after

使用的是dispatch_time_t , 不用考虑runloop是否开启

九、自旋锁和互斥锁

区别:

* 自旋锁会忙等,即在访问被锁资源时,调用者线程不会休眠,而是在不停的循环在那里,知道被锁资源释放锁。
* 互斥锁会休眠,即在访问被锁资源时,调用者会休眠,此时cpu可以调度其他线程工作,知道被锁资源释放锁,此时会唤醒休眠线程。
*自旋锁高效但是消耗cpu,可以在耗时较少的时候使用。
*自旋锁:atomic,OSSpinLock,dispatch_semaphore_t
  互斥锁:pthread_mutex,@synchronized,NSLock,NSConditionLock,NSCondition,NSRecursiveLock(递归锁)

相关文章

  • iOS多线程 NSOperation

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程 pthread、NSThread

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程: GCD

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程运用

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程基础

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • 多线程介绍

    一、进程与线程 进程介绍 线程介绍 线程的串行 二、多线程 多线程介绍 多线程原理 多线程的优缺点 多线程优点: ...

  • iOS进阶之多线程管理(GCD、RunLoop、pthread、

    深入理解RunLoopiOS多线程--彻底学会多线程之『GCD』iOS多线程--彻底学会多线程之『pthread、...

  • iOS多线程相关面试题

    iOS多线程demo iOS多线程之--NSThread iOS多线程之--GCD详解 iOS多线程之--NSOp...

  • 多线程之--NSOperation

    iOS多线程demo iOS多线程之--NSThread iOS多线程之--GCD详解 iOS多线程之--NSOp...

  • iOS多线程之--NSThread

    iOS多线程demo iOS多线程之--NSThread iOS多线程之--GCD详解 iOS多线程之--NSOp...

网友评论

      本文标题:多线程

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