zoukankan      html  css  js  c++  java
  • GCD 信号量使用记录

    需求:

    现在有一个页面,有A, B, C 3个网络请求。A, B是非必须,C是必须,所有请求完毕之后要刷新tableView。

    这里当然可以使用异步并发,每个请求的成功或者失败中刷新tableView。

    如果要用信号量来控制呢?顺便复习一遍吧。

    信号量(Semaphore)是多线程环境下的一种保护设施,可以用来保证两个或多个关键代码不被并发调用。
    
    在进入一个关键代码段之前,线程必须获取一个信号量。一旦执行完毕,该线程就会释放信号量。等待下一个信号量被发送,线程才能继续获取到新信号量并再次执行关键代码段。

    举个例子:
    一个停车场,只能容下5辆车。这时候,来了6辆车。只有前5辆能进去。第6辆车等待,当有一辆车离开停车场时,才能进入。
    这里,
    想进停车场 —— 创建信号,
    当前有车位 ,领卡进场 —— 发信号,
    当前无车位,排队等卡 —— 等信号,
    离开停车场 —— 销毁信号。
     
    dispatch_semaphore_create(long value); //!< 创建信号量
    dispatch_semaphore_signal(dispatch_semaphore_t dsema); //!< 发送信号量 +1

    dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); //!< 等待信号量 -1


    作者:QiShare
    链接:https://www.jianshu.com/p/0ae764495c9b
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
     

    当信号量为<0时就会阻塞线程,>=0时就继续走。发送信号量 +1 & 等待信号量 -1 是成对出现的

    所以 dispatch_semaphore_create(?)函数指定信号量,看情况,一般是指定0

    测试代码:

    -(void)dispatch_group_function1

    {

        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

        

        dispatch_group_t group = dispatch_group_create();

        

        dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{

            

            NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];

            

            NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {

                // 请求完成,可以通知界面刷新界面等操作

                NSLog(@"第一步网络请求完成");

                

                // 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯)

                dispatch_semaphore_signal(semaphore);

            }];

            

            [task resume];

            

            // 以下还要进行一些其他的耗时操作

            NSLog(@"耗时操作继续进行%@",[NSThread currentThread]);

            

            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

        });

        

        dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{

            

            NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]];

            

            NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {

                // 请求完成,可以通知界面刷新界面等操作

                NSLog(@"第二步网络请求完成");

                

                // 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯)

                dispatch_semaphore_signal(semaphore);

            }];

            

            [task resume];

            

            // 以下还要进行一些其他的耗时操作

            NSLog(@"耗时操作继续进行%@",[NSThread currentThread]);

            

            dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

        });

        

        dispatch_group_notify(group, dispatch_get_main_queue(), ^{

            NSLog(@"刷新界面等在主线程的操作");

        });

    }

    打印信息:

    
    

    2020-03-25 11:43:16.034584+0800 GCD信号量Demo[14407:221514] 耗时操作继续进行<NSThread: 0x6000011f9a00>{number = 5, name = (null)}

    
    

    2020-03-25 11:43:16.034584+0800 GCD信号量Demo[14407:221513] 耗时操作继续进行<NSThread: 0x6000011d8400>{number = 6, name = (null)}

    
    

    2020-03-25 11:43:16.138100+0800 GCD信号量Demo[14407:221516] 第一步网络请求完成

    
    

    2020-03-25 11:43:22.544131+0800 GCD信号量Demo[14407:221515] 第二步网络请求完成

    
    

    2020-03-25 11:43:22.544268+0800 GCD信号量Demo[14407:221068] 刷新界面等在主线程的操作

     

    还有一种方法,设置依赖关系,这里我担心的就是,如果A,B请求出了问题,或者失败了,那C请求还会不会继续呢?

    参考https://www.cnblogs.com/tryFighting/p/8178376.html 

    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
        NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
    
            //block队列1
            [self _fetchBannerImageVoList];
        }];
        NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{
    
            //block队列2
            [self _fetchRemindData];
        }];
        NSBlockOperation * op3 = [NSBlockOperation blockOperationWithBlock:^{
    
            //block队列3
            [self _fetchMixArticleVideoData];
        }];
        [op2 addDependency:op1];
        [op3 addDependency:op2];
        [queue addOperation:op1];
        [queue addOperation:op2];
        [queue addOperation:op3];
    此文仅为鄙人学习笔记之用,朋友你来了,如有不明白或者建议又或者想给我指点一二,请私信我。liuw_flexi@163.com/QQ群:582039935. 我的gitHub: (学习代码都在gitHub) https://github.com/nwgdegitHub/
  • 相关阅读:
    How to implement long running flows, sagas, business processes or similar
    What are long running processes?
    The Microservices Workflow Automation Cheat Sheet
    cget cmake 包管理工具
    buckaroo 试用
    buckaroo 去中心化的c++包管理工具
    What's New In Zeebe: Scaling Zeebe, New Client APIs, Faster Requests, Timestamps, NodeJS Client, and Default Topic is Back!
    Benchmarking Zeebe: An Intro to How Zeebe Scales Horizontally and How We Measure It
    Architecture options to run a workflow engine
    camunda 开源的bpm系统
  • 原文地址:https://www.cnblogs.com/liuw-flexi/p/12564975.html
Copyright © 2011-2022 走看看