多线程之并发并行

2018-01-28  本文已影响7人  不懂冯先生

我们在APP开发过程中, 很多情况下会碰到多个网络请求同时存在的要求, 这对我们开发者来说一般会有网络请求之间是否存在依赖关系, 即:上个网络请求结果有没有可能影响到下一个; 这就是计算机发展中的并发问题; 由于是笔者不是计算机专业毕业的学生, 所以对这些不是很了解, 经查阅资料后,将所得记录如下.

并发是指至少两个Action可以同时存在, 并行至少两个Action可以同时run

引用国外大神来区分并发与并存的区别的一张图 并行与并发.jpg

并发初了解

在过去单核CPU时代, 碰到并发问题的时候, 处理方式是多个线程不断交替换入换出内存(上图), 给你一种并发已经解决的错觉, 而现代多核CPU时代, 每一个线程都可以占用一个核心(下图), 这个就是并行解决.

实际运用

我们在开发的过程中可能会碰到一个界面多个网络请求的需求情况;
此时要考虑这几个请求之间的关系, 是不是有相互依赖的关系

一. 多个网路请求彼此依赖
方式之一采用GCD

dispatch_group_t结合信号量dispatch_semaphore_t(或者采用外部变量bool或者数字来记录)来实现

    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_async(group, queue, ^{
        dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
        NSLog(@"__1");
        dispatch_semaphore_signal(semphore);
//        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1* NSEC_PER_SEC)), queue, ^{
//            NSLog(@"1");
//            dispatch_semaphore_signal(semphore);
//        });
    });
    
    dispatch_group_async(group, queue, ^{
        dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
        NSLog(@"__2");
        dispatch_semaphore_signal(semphore);
    });
    
    dispatch_group_notify(group, queue, ^{
//        dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
    });
方式之二采用线程池
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSBlockOperation * bolckOperation = [NSBlockOperation blockOperationWithBlock:^{
        for (NSInteger i = 0; i<2; i++) {
            NSLog(@"%ld__%@", i, [NSThread currentThread]);
        }
    }];
    
    NSBlockOperation * blcokA = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"我是AAAA");
    }];
    // 添加依赖 blcokA需要在bolckOperation操作完成之后才能进行
    [blcokA addDependency:bolckOperation];
    [queue addOperation:bolckOperation];
    [queue addOperation:blcokA];

NSOperationQueue是apple封装GCD的一个新的管理线程的api, 很简单很强大, 而GCD则是封装C的, 简单的多线程建议使用GCD, 复杂点的使用NSOperationQueue
这里想提一下信号量这个概念dispatch_semaphore_t跟信号量相关的函数只有三个dispatch_semaphore_create(long value), dispatch_semaphore_signal(semphore), dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER)/DISPATCH_TIME_NOW, 其中dispatch_semaphore_waitdispatch_semaphore_signal成对出现, signal是发射信号, 信号量加一; wait是接受信号, 信号量减一.

多个网络请求完成后, 集中更新UI

这里采用的是dispatch_group_t

    // 创建信号量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    // 创建全局并行
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{

        dispatch_semaphore_signal(semaphore);
        NSLog(@"yue");
        
    });
    dispatch_group_async(group, queue, ^{

        dispatch_semaphore_signal(semaphore);
        
                NSLog(@"duihuan11");
    });
    dispatch_group_async(group, queue, ^{

        dispatch_semaphore_signal(semaphore);
        
    });
    
    dispatch_group_notify(group, queue, ^{
        // 三个请求对应三次信号等待
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        //在这里 进行请求后的方法,回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            //更新UI操作
            NSLog(@"value: %@", semaphore);
        });
    });

在线程池中取消依赖关系, 可以满足需求

代码地址:Demo

PS: 日积月累, 天天进步!
--END--

上一篇下一篇

猜你喜欢

热点阅读