进程和线程(基础篇)
什么是进程?
其实我们每一个运行的程序都是一个进程,进程之间是相互独立的存在。
什么是线程?
进程想要执行任务需要依赖线程,也就是说线程是进程中的最小执行单位,并且一个进程中至少有一个线程。
什么是多线程?
其实就是进程有多个线程执行任务,为什么会有多线程呢?是因为一个程序在执行的过程中有许多的耗时的操作,比如 io 操作,数据库和磁盘的 io,如果是单线程,那么就要等待当前的任务完成,完了才能执行后续任务,如果任何耗时,那么程序就会处于等待,为了提高效率,其实也就是说为了提高我们 cpu 的使用率,对于单核 cpu 来说,他并不是每个时刻都在使用,在读取磁盘的时候,cpu 处于等待操作,并没有执行任何操作,这个时候我们就可以让 cpu 在等待的这段时间去执行其他的操作,从而提高效率。
多线程的缺点:首先使用多线程会消耗系统的资源,因为每开辟一个线程都需要开辟内存,且线程间的通信也会相对比较耗时。其次,线程的终止对程序会有影响,最后多个线程之间共享数据会出现死锁。
进程间的通信方式有哪些?
- 管道->半双工
- 命名管道
- 信号量
- 消息队列
- 共享内存
- 套接字
- 全双工管道
线程间的通信方式有哪些?
- 互斥锁:提供了以排他方式防止数据结构被并发修改的方法。
- 读写锁:允许多个线程同时共享数据,而对写操作是互斥的。
- 条件变量:可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。
什么是线程安全?
线程安全就是当一个线程在进行数据访问的时候,其他的线程不能对其进行访问,直到该线程访问结束,其他的线程才能进行访问。只有确保这样,才能使数据不被其他线程影响。线程不安全,则是同一个时刻,多个线程对某一数据进行访问,从而导致我们达不到预期的效果,这个就是线程不安全。
如何保证线程安全?
通常我们使用锁的机制来保证线程安全,即确保同一时刻只有同一个线程来对同一个数据源进行访问。
说说你了解的锁?每一种都怎么用?
- OSSpinLock:自旋锁,当我们再使用这种锁的时候,编译器会报警告,原因是苹果已经废弃了这种锁了,因为在某些特定场景下,它已经不安全了,这是“忙等”的锁
- 互斥锁(Mutex):是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写的机制。该目的通过将代码切片成一个一个的临界区而达成。在 YYKit 的源码中,很多地方都使用了这种锁
- 信号量:是一种更高级的同步机制,互斥锁可以说是semaphore在仅取值0/1时的特例。信号量可以有更多的取值空间,用来实现更加复杂的同步,而不单单是线程间互斥。
- 条件锁:就是条件变量,当进程的某些资源要求不满足时就进入休眠,也就是锁住了。当资源被分配到了,条件锁打开,进程继续运行。
iOS 中常用的锁?
@synchronized、NSLock、NSCondition、NSRecuiveLock、dispatch_semaphore、pthread_mutex、OSSpinLock、os_unfair_lock
iOS 中有几种线程?他们之间的区别是什么?
NSThread、GCD、NSOperation、NSOpreationqueue
GCD 和 NSOperation 有什么区别?
GCD 自身不能控制线程的状态
NSOperation 可以控制线程的状态,如何控制?
进程和线程(实战篇)
如何使线程保活?(如何实现常驻线程的实现,NSThread 相关)
- 创建一个线程,并且开启当前线程的 runloop
- 向该 runloop 中添加source/port 等事件维持该 runloop 的事件循环
- 启动 runloop
如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)
@interface GCDGroup () {
dispatch_queue_t downloadImageQueue;
NSMutableArray <NSURL *> *imageUrlArray;
}
@end
@implementation GCDGroup
- (instancetype)init {
self = [super init];
if (self) {
// 创建并发队列
downloadImageQueue = dispatch_queue_create("downloadImage_queue", DISPATCH_QUEUE_CONCURRENT);
imageUrlArray = [NSMutableArray array];
}
return self;
}
- (void)downloadImag {
// 创建异步 group
dispatch_group_t group = dispatch_group_create();
for (NSURL *url in imageUrlArray) {
// 将组分发到并发队列中
dispatch_group_async(group, downloadImageQueue, ^{
// 下载图片
NSLog(@"url is %@", url);
});
}
// 下载完成
dispatch_group_notify(group, downloadImageQueue, ^{
NSLog(@"download finished");
});
}
dispatch_barrier_async的作用是什么?
主要是实现多读单写,保证线程安全
网友评论