信号量的使用场景

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

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);
    });
}

 

posted @ 2019-02-27 11:17  小太阳521  阅读(1973)  评论(0编辑  收藏  举报