美文网首页
iOS 面试 -- 进程和线程

iOS 面试 -- 进程和线程

作者: 唐师兄 | 来源:发表于2020-03-16 17:10 被阅读0次

    进程和线程(基础篇)

    什么是进程?

    其实我们每一个运行的程序都是一个进程,进程之间是相互独立的存在。


    什么是线程?

    进程想要执行任务需要依赖线程,也就是说线程是进程中的最小执行单位,并且一个进程中至少有一个线程。


    什么是多线程?

    其实就是进程有多个线程执行任务,为什么会有多线程呢?是因为一个程序在执行的过程中有许多的耗时的操作,比如 io 操作,数据库和磁盘的 io,如果是单线程,那么就要等待当前的任务完成,完了才能执行后续任务,如果任何耗时,那么程序就会处于等待,为了提高效率,其实也就是说为了提高我们 cpu 的使用率,对于单核 cpu 来说,他并不是每个时刻都在使用,在读取磁盘的时候,cpu 处于等待操作,并没有执行任何操作,这个时候我们就可以让 cpu 在等待的这段时间去执行其他的操作,从而提高效率。
    多线程的缺点:首先使用多线程会消耗系统的资源,因为每开辟一个线程都需要开辟内存,且线程间的通信也会相对比较耗时。其次,线程的终止对程序会有影响,最后多个线程之间共享数据会出现死锁。


    进程间的通信方式有哪些?

      1. 管道->半双工
      1. 命名管道
      1. 信号量
      1. 消息队列
      1. 共享内存
      1. 套接字
      1. 全双工管道

    线程间的通信方式有哪些?

      1. 互斥锁:提供了以排他方式防止数据结构被并发修改的方法。
      1. 读写锁:允许多个线程同时共享数据,而对写操作是互斥的。
      1. 条件变量:可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。

    什么是线程安全?

    线程安全就是当一个线程在进行数据访问的时候,其他的线程不能对其进行访问,直到该线程访问结束,其他的线程才能进行访问。只有确保这样,才能使数据不被其他线程影响。线程不安全,则是同一个时刻,多个线程对某一数据进行访问,从而导致我们达不到预期的效果,这个就是线程不安全。

    如何保证线程安全?

    通常我们使用锁的机制来保证线程安全,即确保同一时刻只有同一个线程来对同一个数据源进行访问。

    说说你了解的锁?每一种都怎么用?

      1. OSSpinLock:自旋锁,当我们再使用这种锁的时候,编译器会报警告,原因是苹果已经废弃了这种锁了,因为在某些特定场景下,它已经不安全了,这是“忙等”的锁
      1. 互斥锁(Mutex):是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写的机制。该目的通过将代码切片成一个一个的临界区而达成。在 YYKit 的源码中,很多地方都使用了这种锁
      1. 信号量:是一种更高级的同步机制,互斥锁可以说是semaphore在仅取值0/1时的特例。信号量可以有更多的取值空间,用来实现更加复杂的同步,而不单单是线程间互斥。
      1. 条件锁:就是条件变量,当进程的某些资源要求不满足时就进入休眠,也就是锁住了。当资源被分配到了,条件锁打开,进程继续运行。

    iOS 中常用的锁?

    @synchronized、NSLock、NSCondition、NSRecuiveLock、dispatch_semaphore、pthread_mutex、OSSpinLock、os_unfair_lock

    iOS 中有几种线程?他们之间的区别是什么?

    NSThread、GCD、NSOperation、NSOpreationqueue

    GCD 和 NSOperation 有什么区别?

    GCD 自身不能控制线程的状态
    NSOperation 可以控制线程的状态,如何控制?


    进程和线程(实战篇)

    如何使线程保活?(如何实现常驻线程的实现,NSThread 相关)

    1. 创建一个线程,并且开启当前线程的 runloop
    2. 向该 runloop 中添加source/port 等事件维持该 runloop 的事件循环
    3. 启动 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的作用是什么?

    主要是实现多读单写,保证线程安全

    相关文章

      网友评论

          本文标题:iOS 面试 -- 进程和线程

          本文链接:https://www.haomeiwen.com/subject/axrnehtx.html