iOS 多线程的概念、原理

图1.png

线程和进程的关系和区别

线程定义
  • 线程是进程的基本执行单元,一个进程的全部任务都在线程中执行
  • 进程要想执行任务,必须得有线程,进程至少要有一条线程
  • 程序启动会默认开启一条线程,这条线程被称为主线程或 UI 线程
进程定义
  • 进程是指在系统中正在运行的一个应用程序ios

  • 每一个进程之间是独立的,每一个进程均运行在其专用的且受保护的内存空间内macos

  • 经过“活动监视器”能够查看 Mac 系统中所开启的进程 #####进程与线程的区别安全

  • 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。bash

  • 资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,可是进程之间的资源是独立的。网络

  • 一个进程崩溃后,在保护模式下不会对其余进程产生影响,可是一个线程崩溃整个进程都死掉。因此多进程要比多线程健壮。多线程

  • 进程切换时,消耗的资源大,效率高。因此涉及到频繁的切换时,使用线程要好于进程。一样若是要求同时进行而且又要共享某些变量的并发操做,只能用线程不能用进程并发

  • 执行过程:每一个独立的进程有一个程序运行的入口、顺序执行序列和程序入口。可是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。性能

  • 线程是处理器调度的基本单位,可是进程不是。ui

多线程的意义

优势

  • 能适当提升程序的执行效率
  • 能适当提升资源的利用率(CPU,内存)
  • 线程上的任务执行完成后,线程会自动销毁

缺点

  • 开启线程须要占用必定的内存空间(默认状况下,每个线程都占 512 KB)
  • 若是开启大量的线程,会占用大量的内存空间,下降程序的性能
  • 线程越多,CPU 在调用线程上的开销就越大
  • 程序设计更加复杂,好比线程间的通讯、多线程的数据共享
    图2.png

好像主线程也是512KB,而不是1MBspa

多线程的原理

图3.png

多线程的生命周期

图4.png

  • 新建线程,执行start,线程必须start,不然没有做用。但也不能够重复start,会致使崩溃
  • 线程start后,将会进入Runnable状态。
  • 进入Runnable状态后,进入Running状态,当前线程会被CPU调度。也有可能在进入Running状态后,线程切换,返回Runnable状态

CPU如何调度线程?线程池的原理

图5-线程池参数.png
图6-线程池的原理.png
1.系统有一个可调度线程池,若是线程池里有这个线程,就会开始执行。 2.若是没有,将判断线程池大小是否小于核心线程池大小,若是小于,那将会开辟新的线程来执行任务。 3.若是大于线程池,表明线程池没有能力再去开辟新的线程,只能依赖于原有的线程去执行 ,就将判断工做队列是否已满,若是没满就将任务提交到工做队列,等待执行任务。 4.满了的话,线程池就会判断全部线程是否都在工做,若是有空闲的线程,就让这条线程去执行任务。 5.若是仍是没有空闲的线程,就将任务交给 饱和策略。 6.饱和策略分为四种

Abort策略:默认策略,新任务提交时直接抛出未检查的异常RejectedExecutionException,该异常可由调用者捕获。 CallerRuns策略:为调节机制,既不抛弃任务也不抛出异常,而是将某些任务回退到调用者。不会在线程池的线程中执行新的任务,而是在调用exector的线程中运行新的任务。 Discard策略:新提交的任务被抛弃。 DiscardOldest策略:队列的是“队头”的任务,而后尝试提交新的任务。(不适合工做队列为优先队列场景)

  • Running后,有可能任务会形成堵塞,当形成堵塞的任务执行结束后,一样会回到Runnable状态,继续执行Running
  • 死亡,分为任务执行结束跟强制退出线程exit

线程操做

查看NSThread相关文件能够看到,线程有多种状态,能够根据不一样状况,判断线程的状态,来作不一样的操做。可经过重写下面的方法掌握线程的生命周期(YYKit)。 通常状况下,咱们不多去停止一个网络请求,按照通常的状况,是没办法停止的,可是依靠线程,经过关闭线程,从而达到停止网络请求的目的。

@property (readonly, getter=isExecuting) BOOL executing API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
@property (readonly, getter=isFinished) BOOL finished API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
@property (readonly, getter=isCancelled) BOOL cancelled API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));

- (void)cancel API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
- (void)start API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
- (void)main API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));	// thread body method
复制代码

线程安全

这是一张经典的多线程比喻图。多端增删改查。

图7.png

如何避免上图的状况?如何保证线程安全? 上锁

相关文章
相关标签/搜索