线程和进程的定义
-
线程
是进程的基本执行单元,一个进程
的所有任务都在线程
中执行 -
进程
要想执行任务,必须要有线程
,进程至少要有一条线程
-
iOS应用程序会默认开启一条
线程
,我们通常称之为主线程
或UI线程
-
进程
是指在系统中正在运行的程序,比如我们的app -
每个
进程
是独立的,每个进程运行在专有的内存空间内。
-
地址空间
:同⼀进程
的线程
共享本进程
的地址空间,⽽进程
之间则是独⽴的地址空间 -
资源拥有
:同⼀进程
内的线程共享本进程
的资源如内存、I/O、cpu等,但是进程之间的资源是独⽴的
多线程的意义
多线程原理
-
时间碎片
:多线程实际上cpu在多个任务之间进行快速的切换,这个时间间隔就是时间片 -
多线程
实际上就是,cpu快速的在多个线程之前切换,cpu如果调度的时间足够快,就会造成多线程同时执行的假想
常用的多线程技术
- pthread
- NSthread
- GCD
- NSOperation pthread:
pthread_t threadId = NULL;
//c字符串
char *cString = "pthreadCode";
int result = pthread_create(&threadId, NULL, pthreadTest, cString);
if (result == 0) {
NSLog(@"成功");
} else {
NSLog(@"失败");
}
void *pthreadTest(void *para){
// 接 C 语言的字符串
// NSLog(@"===> %@ %s", [NSThread currentThread], para);
// __bridge 将 C 语言的类型桥接到 OC 的类型
NSString *name = ( __bridge NSString *)(para);
NSLog(@"===>%@ %@", [NSThread currentThread], name);
return NULL;
}
NSthread 、GCD、NSOperation
线程的生命周期
同步锁和自旋锁
当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题。为了解决线程安全的问题,开发过程中通常需要加锁。锁又分为同步锁
和自旋锁
。它们可以应对不同的场景。
- 同步锁:保证同一时间内,只有一条线程能够执行。加了互斥做的代码,当新线程访问时,如果发现其他线程正在执行锁定的代码,新线程就会进入休眠 比如:
@synchronized(锁对象) {
// 需要锁定的代码
}
- 自旋锁:加了自旋锁,当新线程访问代码时,如果发现有其他线程正在锁定代码,新线程会用死循环的方式,一直等待锁定的代码执行完成。相当于不停尝试执行代码,比较消耗性能
比如常见的
atomic
,内部就是用自旋锁实现的。
多线程之GCD
- 什么是GCD? 全称Grand Central Dispatch(中央大调度),纯C语言,提供了非常多强大的函数。
- GCD的优势
- GCD是苹果公司为多核并行运行计算提出的解决方案
- GCD会利用更多的cpu内核(比如双核,四核)
- CGD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
同步函数和异步函数
dispatch_block_t
:任务使用block封装
dispatch_async
:异步函数
- 不用等待当前语句执行完毕,就可以执行下一条语句
- 会开启线程执行block任务
- 异步是多线程的代名词
dispatch_sync
:同步函数
- 必须等待当前语句执行完成,才会执行下一条语句
- 不会开启线程
- 在当前线程执行block任务
串行队列和并行队列
如下图:
函数与队列搭配使用的几种情况
- 同步函数串行队列
- 不会开启线程,在当前线程执行任务
- 任务串行执行,任务一个接一个
- 会产生堵塞
- 同步函数并发队列
- 不会开启线程,在当前线程执行任务
- 任务一个接一个
- 异步函数串行队列
-
开启新线程,
-
任务一个接一个执行 4.异步函数并发队列
-
开启线程
-
任务异步执行,执行顺序和cpu调度有关