zoukankan      html  css  js  c++  java
  • 信号量的使用场景

    开发中经常会遇到如下两种业务场景:

    1 某一个界面需要同时发多个请求,全部请求都成功后再一起刷新界面

    2 多个请求必须按照一定顺序执行

    3 控制线程开启的数量

    这时信号量的作用就显得很牛逼了

    信号量常用的三个方法如下所示:

    • dispatch_semaphore_create:创建一个信号量(semaphore
    • dispatch_semaphore_signal:信号通知,即让信号量+1
    • dispatch_semaphore_wait:等待,直到信号量大于0时,即可操作,同时将信号量-1

    问题1解决方案:

     dispatch_group_t group = dispatch_group_create();
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            //请求1
      dispatch_semaphore_t sema = dispatch_semaphore_create(0);
                [网络请求:{
                 成功:dispatch_semaphore_signal(sema);
                失败:dispatch_semaphore_signal(sema);
                }];
                 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    
        });
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            //请求2
     dispatch_semaphore_t sema = dispatch_semaphore_create(0);
                [网络请求:{
                 成功:dispatch_semaphore_signal(sema);
                失败:dispatch_semaphore_signal(sema);
                }];
                 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    }); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //请求3
     dispatch_semaphore_t sema = dispatch_semaphore_create(0);
                [网络请求:{
                 成功:dispatch_semaphore_signal(sema);
                失败:dispatch_semaphore_signal(sema);
                }];
                 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ //界面刷新 NSLog(@"任务均完成,刷新界面"); });

    问题2解决方案

    //第一步:获取token
        NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
            [self task_1];
        }];
    
      //第二步:上传七牛
        NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
            [self task_2];
        }];
    
       //第三步:图片地址上传服务器
        NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
            [self task_3];
        }];
    
        //设置依赖
        [operation2 addDependency:operation1];      //任务二依赖任务一
        [operation3 addDependency:operation2];      //任务三依赖任务二
    
        //创建队列
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        [queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO];
    - (void)task_1
    {
        //创建信号量并设置计数默认为0
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    
        [self.entityRequest postGetQiNiuTokenSuccess:^(NS_M_RequestOutput *json) {
           //请求成功 计数+1操作
            dispatch_semaphore_signal(sema);
        } failure:^(NSString *msg) {
           //请求失败 计数+1操作
            dispatch_semaphore_signal(sema);
        } error:^(NSError *error) {
           //请求异常 计数+1操作
            dispatch_semaphore_signal(sema);
        }];
        
        //若计数为0则一直等待
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    }
    - (void)task_2
    {
        //创建信号量并设置计数默认为0
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    
        [self.entityRequest postGetQiNiuTokenSuccess:^(NS_M_RequestOutput *json) {
           //请求成功 计数+1操作
            dispatch_semaphore_signal(sema);
        } failure:^(NSString *msg) {
           //请求失败 计数+1操作
            dispatch_semaphore_signal(sema);
        } error:^(NSError *error) {
           //请求异常 计数+1操作
            dispatch_semaphore_signal(sema);
        }];
        
        //若计数为0则一直等待
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    }

    - (void)task_3
    {
        //创建信号量并设置计数默认为0
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    
        [self.entityRequest postGetQiNiuTokenSuccess:^(NS_M_RequestOutput *json) {
           //请求成功 计数+1操作
            dispatch_semaphore_signal(sema);
        } failure:^(NSString *msg) {
           //请求失败 计数+1操作
            dispatch_semaphore_signal(sema);
        } error:^(NSError *error) {
           //请求异常 计数+1操作
            dispatch_semaphore_signal(sema);
        }];
        
        //若计数为0则一直等待
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    }
    问题3解决方案(控制允许同时并发的操作最多只有5次)
    dispatch_semaphore_t sema = dispatch_semaphore_create(5);
    for (100次循环操作) {
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 操作
            dispatch_semaphore_signal(sema);
        });
    }
  • 相关阅读:
    面向对象和网络编程补充
    元类与网络编程
    类的继承
    面向过程
    身为一个小白,看到一篇值得看的文章。讲述小白学习python的6个方法。
    2019.08.02 学习整理
    2019.08.01学习整理
    2017.07.31 学习整理
    2019.07.30 学习整理
    2019.7.29学习整理python
  • 原文地址:https://www.cnblogs.com/jinlongyu123/p/10442457.html
Copyright © 2011-2022 走看看