美文网首页
多线程之并发并行

多线程之并发并行

作者: 不懂冯先生 | 来源:发表于2018-01-28 16:46 被阅读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--

    相关文章

      网友评论

          本文标题:多线程之并发并行

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