一 什么是进程
进程是在系统中正在运行的应用程序!普通的应用程序并不是进程,只有正在运行的应用程序才是一个进程,
在系统中每个进程之间是相互独立的,每个进程均在其专享的且受保护的内存空间内。但是一个应用程序可以对用多个进程,比如 你可以在MAC上打开两个QQ。
二 什么是线程
一个进程想要执行任务 必须得有进程(每一个进程至少包含一个线程)
一个进程(程序)的所有任务 都在线程中完成。
2.1 线程的串行
线程里面任务的执行顺序是串行的,就是一个线程中执行任务时有顺序的,一个接一个的,如果一个线程中有多个任务,这些任务是一个接一个完成的,在同一时间内 一个线程只能执行一个任务.也可以说线程是进程中的一个执行路径。
2.2 进程和线程的关系
线程是CPU调用(执行任务)的最小单位
进程是CPU分配资源和调度单位 (CPU 调度进程 进程调用线程执行任务)
一个程序可以对应多个进程,一个进程至少包含一个线程
同一个进程內的线程共享进程的资源
三 多线程
一个进程中可以开启多个线程,每条线程可以并行(同时)执行不同的任务(但是每条线程执行任务时串行的)
3.1 多线程的原理
在同一时间内CPU职能处理一条线程,只有一条线程在工作
多线程并发(同时)执行,其实是CPU快速在多条线程之间的调度(切换)
上面的理论只存在在单CPU之间
如果CPU调度线程的时间足够快就会造成多线程并发的假象.
所以并不是开辟越多的线程就越好,因为CPU在调度线程的时候也会消耗资源(比如保存上下文 即每条线程执行任务的进度节点) 通常我们在开发中会开3-5条线程
3.2多线程的优缺点
优点
1.可以适当的提高程序的执行效率
2.能适当的提高资源利用率(CPU,内存利用率)
缺点
创建多线程是有开销的,在ISO下主要成本包括,内核数据结构(大约1KB) 栈空间(自线程512KB 注线程1MB,也可以通过setStackSize: 来设置,但必须是4K的倍数,而且最小是16K)创建线程大约需要90毫秒的创建时间.
如果开启大量的线程 会降低程序的性能
线程越多,CPU在调度线程上的开销就会越大
线程设计更加复杂,比如线程之间的通信,多线程数据共享 等等
四 多线程在IOS中的应用
4.1 什么是主线程
一个iOS程序运行之后,默认会开启一条线程,这个线程就叫做主线程(UI线程)
主线程的主要任务是 显示、刷新UI界面 处理UI事件(点击事件 滚动事件 拖拽事件)
凡是跟UI相关的所有操作 必须在主线程之间运行 但是不要把耗时操作放到主线程之间
因为耗时操作会卡住主线程,给用户造成卡顿的感觉(因为线程中的任务是串行执行的,会等到耗时操作完成后才执行其他任务)
耗时操作的执行最好放在子线程中(后台线程,非主线程) 比如打印就是耗时操作
一些简单代码
- (void)viewDidLoad { [super viewDidLoad]; //获取主线程 NSThread *mainThread = [NSThread mainThread]; //获取当前此案成 NSThread *currentThread = [NSThread currentThread]; NSLog(@"主线程 %@ 当前线程%@",mainThread,currentThread); //判断是否为主线程 // 判断number == 1 //类方法 BOOL isMainThread = [NSThread isMainThread]; //对象方法 BOOL isMainThread1 = [currentThread isMainThread]; NSLog(@"%zd --- %zd",isMainThread,isMainThread1); }
五 iOS中多线程的实现方案
六Pthread的简单实用
#import "ViewController.h" #import <pthread.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self openThreadByPthread]; } - (void)openThreadByPthread { pthread_t thread; /* *第一个参数:线程对象的地址 *第二个参数:线程的一些属性 不想传久NULL *第三个参数:指向函数的指针 *第四个参数:函数需要接受的参数 不需要传NULL */ pthread_create(&thread, NULL, task, NULL); } //多线程要执行的函数 void * _Nullable task(void * _Nullable params) { NSLog(@"%@",[NSThread currentThread]); return NULL; }