线程和进程的定义
- 线程是进程的基本执行单元,一个进程的所有任务都在线程中执行。
- 进程想要执行任务,必须得有线程,进程至少要有一条线程。
- 程序启动会默认开启一条线程这条线程被称为主线程或UI线程。
- 进程是指系统中正在运行的一个程序
- 每个进程之间都是独立的。每个进程均运行在其专用的受保护的内存空间内
-通过mac的活动监视器可以查看所有开启的进程
多线程意义
- 优点
- 能适当提高程序的执行效率
- 能适当提高资源的利用率(CPU,内存)
- 线程上的任务执行完成后,线程会自动销毁
- 缺点
- 开启线程需要占用一定的内存空间(默认情况下,每一个线程都占 512 KB)
- 如果开启大量的线程,会占用大量的内存空间,降低程序的性能
- 线程越多,CPU 在调用线程上的开销就越大
- 程序设计更加复杂,比如线程间的通信、多线程的数据共享
线程生命周期
线程池
#饱和策略
AbortPolicy 直接抛出RejectedExecutionExeception异常来阻止系统正常运行
CallerRunsPolicy 将任务回退到调用者
DisOldestPolicy 丢掉等待最久的任务
DisCardPolicy 直接丢弃任务
这四种拒绝策略均实现的RejectedExecutionHandler接口
GCD概念
GCD 简介
什么是GCD?
全称是 Grand Central Dispatch
纯 C 语言,提供了非常多强大的函数
GCD的优势
GCD 是苹果公司为多核的并行运算提出的解决方案
GCD 会自动利用更多的CPU内核(比如双核、四核)
GCD 会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
程序员只需要告诉 GCD 想要执行什么任务,不需要编写任何线程管理代码
线程和Runloop的关系
1:runloop与线程是一一对应的,一个runloop对应一个核心的线程,为什么说是核心的,是因为runloop是可以嵌套的,但是核心的只能有一个,他们的关系保存在一个全局的字典里。
2:runloop是来管理线程的,当线程的runloop被开启后,线程会在执行完任务后进入休眠状态,有了任务就会被唤醒去执行任务。
3:runloop在第一次获取时被创建,在线程结束时被销毁。
4:对于主线程来说,runloop在程序一启动就默认创建好了。
5:对于子线程来说,runloop是懒加载的,只有当我们使用的时候才会创建,所以在子线程用定时器要注意:确保子线程的runloop被创建,不然定时器不会回调。
函数与队列
队列 -死锁
开发中队列 分为
-
串行队列:
-
并发队列:
需要注意一点就是队列遵循FTFO原则,然后串行队列跟并发队列的根本区别就是DQF_WIDTH,串行是1 并发最多是64 , 指的是一个队列最多可以同时进行的线程。
所以当我们执行下面代码时会出现死锁。原因是当执行到执行sync的queue任务之前需要先把async的queue任务先执行完毕,但是sync的queue任务执行完需要先执行完async的queue的任务,造成了死锁。
原因就是串行队列只能同时执行一个queue的任务(FIFO),而并发队列则不需要可以同时执行多个queue的任务因为给其设置了足够的DQF_WIDTH
dispatch_queue_t queue = dispatch_queue_create("Jqueue",DISPATCH_QUEUE_SERIAL);
NSLog(@"1"):
dispatch_async(queue,^{
NSLog(@"2"):
dispatch_sync(queue,^{
NSLog(@"3");
})
NSLog(@"4");
})
NSLog(@"5");