iOS开发-面试iOS多线程GCD篇

iOS GCD有几种队列

2018-07-25  本文已影响38人  Rumbles

线程和队列

线程和队列完全就是完全不搭边的两个概念,线程就是你cpu的处理能力,队列就是一个任务容器,cpu从容器中取出任务,然后放到线程去执行 ,他俩之间就这点联系


GCD:

GCD:其实就是不用我们创建线程池GCD已经帮我们创建好了,他会帮我们创建线程,销毁线程决定着你的代码块将在哪个线程被执行,还根据可用的系统资源对这些线程进行管理


NSThread打印分析

<NSThread: 0x60c000461c40>{number = 3, name = (null)} Thread 3 子线程
<NSThread: 0x60800006dd80>{number = 1, name = main} 主线程 主线程number就是1


如何使用多线程

我们使用多线程的时候 应该首先创建队列 在想队列里面添加任务(同步任务和异步任务)
1.如何创建队列?
串行队列(主队列)和并行队列(全局队列)
dispatch_queue_t chuanxingduilie = dispatch_queue_create("chuanxingduilie", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_queue_t bingxingduilie = dispatch_queue_create("bingxingduilie", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);

2.什么是串行队列?
dispatch_sync:依次完成每一任务 (上一个执行完下一个才执行)
dispatch_async :子线程里面依次完成每一任务

3.什么是并行队列?
dispatch_sync:依次完成每一任务
dispatch_async :任务是按顺序放到不同的线程执行,但是执行完的顺序不确定

4.什么是任务?
dispatch_sync 同步阻塞执行不会开启新的线程 并且会等待自己执行完才会执行后面的
dispatch_async 异步执行 会开启新的线程(dispatch_async(dispatch_get_main_queue() 不会)


什么是线程安全?

有且只有一个线程写操作 允许同时多个线程读操作
就是我银行卡有2000 那么我存取的时候会把它锁住,保证只有一个对象操作这个数据。
iOS-SDK只提供了非线程安全的数组
iOS中如何保证数组线程安全呢?

dispatch_queue_t syncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- (NSString*)name {
    __block NSString *myName;
    dispatch_sync(syncQueue, ^{
        myName = _name;
    });
    return myName;
}

- (void)setName:(NSString*)name {
    dispatch_barrier_async(syncQueue, ^{
        _name = name;
    });
}

GCD其他函数

dispatch_barrier_async:栅栏函数;队列里面的 前面执行完 才会执行后面的
dispatch_suspend(queue):函数挂起指定的Dispatch Queue
dispatch_resume(queue):函数恢复指定的dispatch Queue

dispatch_after:延迟函数

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"---%@",[NSThread currentThread]);
    });
    // 2s中之后调用run方法
    [self performSelector:@selector(run) withObject:nil afterDelay:2.0];
    // repeats:YES 是否重复
    [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];

dispatch_group:多个处理全部请求结束后想要执行结果处理

    // 创建队列组
    dispatch_group_t group = dispatch_group_create();
    // 创建并行队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    // 执行队列组任务
    dispatch_group_async(group, queue, ^{
        NSLog(@"队列组 ---1---%@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        for (int i = 0; i<10000000; i++) {
        }
        NSLog(@"队列组 ---2---%@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"队列组 ---3---%@",[NSThread currentThread]);
    });
    //队列组中的任务执行完毕之后,执行该函数
    dispatch_group_notify(group, queue, ^{
         NSLog(@"队列组 ---notify---%@",[NSThread currentThread]);
    });

dispatch_once:函数是保证在应用程序执行中只执行一次指定处理的API

+ (instancetype)sharedInstance {
    static ClassName *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc]init];
    });
    return sharedInstance;
}

Dispatch Semaphore:可以设置线程数量的函数

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //任务1
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 1");
        sleep(1);
        NSLog(@"complete task 1");
        dispatch_semaphore_signal(semaphore);
    });
    //任务2
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 2");
        sleep(1);
        NSLog(@"complete task 2");
        dispatch_semaphore_signal(semaphore);
    });
    //任务3
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 3");
        sleep(1);
        NSLog(@"complete task 3");
        dispatch_semaphore_signal(semaphore);
    });

dispatch_apply:该函数是dispatch_sync函数和Dispatch Group的关联API。按照指定的次数将指定的Block追加到指定的Dispatch Queue中,并等待全部处理执行结束

    dispatch_queue_t queue111 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_apply(10, queue111, ^(size_t index) {
        NSLog(@"%zu",index);
    });
上一篇 下一篇

猜你喜欢

热点阅读